This commit is contained in:
squall-leonhart 2010-02-24 00:24:24 +00:00
parent 4a0fe6cfd2
commit 0e8dbcb2bd
136 changed files with 0 additions and 41407 deletions

View File

@ -1,237 +0,0 @@
7z ANSI-C Decoder 4.48
----------------------
7z ANSI-C Decoder 4.48 Copyright (C) 1999-2006 Igor Pavlov
7z ANSI-C provides 7z/LZMA decoding.
7z ANSI-C version is simplified version ported from C++ code.
LZMA is default and general compression method of 7z format
in 7-Zip compression program (www.7-zip.org). LZMA provides high
compression ratio and very fast decompression.
LICENSE
-------
Read lzma.txt for information about license.
Files
---------------------
7zAlloc.* - Allocate and Free
7zBuffer.* - Buffer structure
7zCrc.* - CRC32 code
7zDecode.* - Low level memory->memory decoding
7zExtract.* - High level stream->memory decoding
7zHeader.* - .7z format constants
7zIn.* - .7z archive opening
7zItem.* - .7z structures
7zMain.c - Test application
7zMethodID.* - MethodID structure
7zTypes.h - Base types and constants
How To Use
----------
You must download 7-Zip program from www.7-zip.org.
You can create .7z archive with 7z.exe or 7za.exe:
7za.exe a archive.7z *.htm -r -mx -m0fb=255
If you have big number of files in archive, and you need fast extracting,
you can use partly-solid archives:
7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
512KB for extracting one file from such archive.
Limitations of current version of 7z ANSI-C Decoder
---------------------------------------------------
- It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
- It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
- It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
These limitations will be fixed in future versions.
Using 7z ANSI-C Decoder Test application:
-----------------------------------------
Usage: 7zDec <command> <archive_name>
<Command>:
e: Extract files from archive
l: List contents of archive
t: Test integrity of archive
Example:
7zDec l archive.7z
lists contents of archive.7z
7zDec e archive.7z
extracts files from archive.7z to current folder.
How to use .7z Decoder
----------------------
.7z Decoder can be compiled in one of two modes:
1) Default mode. In that mode 7z Decoder will read full compressed
block to RAM before decompressing.
2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
compressed block by parts. And you can specify desired buffer size.
So memory requirements can be reduced. But decompressing speed will
be 5-10% lower and code size is slightly larger.
Memory allocation
~~~~~~~~~~~~~~~~~
7z Decoder uses two memory pools:
1) Temporary pool
2) Main pool
Such scheme can allow you to avoid fragmentation of allocated blocks.
Steps for using 7z decoder
--------------------------
Use code at 7zMain.c as example.
1) Declare variables:
inStream /* implements ISzInStream interface */
CArchiveDatabaseEx db; /* 7z archive database structure */
ISzAlloc allocImp; /* memory functions for main pool */
ISzAlloc allocTempImp; /* memory functions for temporary pool */
2) call InitCrcTable(); function to initialize CRC structures.
3) call SzArDbExInit(&db); function to initialize db structures.
4) call SzArchiveOpen(inStream, &db, &allocMain, &allocTemp) to open archive
This function opens archive "inStream" and reads headers to "db".
All items in "db" will be allocated with "allocMain" functions.
SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
5) List items or Extract items
Listing code:
~~~~~~~~~~~~~
{
UInt32 i;
for (i = 0; i < db.Database.NumFiles; i++)
{
CFileItem *f = db.Database.Files + i;
printf("%10d %s\n", (int)f->Size, f->Name);
}
}
Extracting code:
~~~~~~~~~~~~~~~~
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
If you need to decompress more than one file, you can send these values from previous call:
blockIndex,
outBuffer,
outBufferSize,
You can consider "outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
After decompressing you must free "outBuffer":
allocImp.Free(outBuffer);
6) call SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
Memory requirements for .7z decoding
------------------------------------
Memory usage for Archive opening:
- Temporary pool:
- Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
- Memory for uncompressed .7z headers
- some other temporary blocks
- Main pool:
- Memory for database:
Estimated size of one file structures in solid archive:
- Size (4 or 8 Bytes)
- CRC32 (4 bytes)
- LastWriteTime (8 bytes)
- Some file information (4 bytes)
- File Name (variable length) + pointer + allocation structures
Memory usage for archive Decompressing:
- Temporary pool:
- Memory for compressed solid block (if _LZMA_IN_CB is not defined)
- Memory for LZMA decompressing structures
- Main pool:
- Memory for decompressed solid block
- Memory for temprorary buffers, if BCJ2 fileter is used. Usually these
temprorary buffers can be about 15% of solid block size.
If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for
compressed blocks. Instead of this, you must allocate buffer with desired
size before calling 7z Decoder. Use 7zMain.c as example.
EXIT codes
-----------
7z Decoder functions can return one of the following codes:
#define SZ_OK (0)
#define SZE_DATA_ERROR (1)
#define SZE_OUTOFMEMORY (2)
#define SZE_CRC_ERROR (3)
#define SZE_NOTIMPL (4)
#define SZE_FAIL (5)
#define SZE_ARCHIVE_ERROR (6)
LZMA Defines
------------
_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements
_SZ_FILE_SIZE_32 - define it if you need only support for files smaller than 4 GB
_SZ_NO_INT_64 - define it if your compiler doesn't support long long int or __int64.
_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
---
http://www.7-zip.org
http://www.7-zip.org/support.html

View File

@ -1,32 +0,0 @@
/* 7zCrc.c */
#include "7zCrc.h"
#define kCrcPoly 0xEDB88320
UInt32 g_CrcTable[256];
void MY_FAST_CALL CrcGenerateTable(void)
{
UInt32 i;
for (i = 0; i < 256; i++)
{
UInt32 r = i;
int j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
}
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
const Byte *p = (const Byte *)data;
for (; size > 0 ; size--, p++)
v = CRC_UPDATE_BYTE(v, *p);
return v;
}
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{
return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
}

View File

@ -1,21 +0,0 @@
/* 7zCrc.h */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
#include <stddef.h>
#include "Types.h"
extern UInt32 g_CrcTable[];
void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_INIT_VAL 0xFFFFFFFF
#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
#endif

View File

@ -1,119 +0,0 @@
/* Alloc.c */
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdlib.h>
#include "Alloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#endif
void *MyAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
#endif
return malloc(size);
}
void MyFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
#endif
free(address);
}
#ifdef _WIN32
void *MidAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES
#endif
#ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif
void SetLargePageSize()
{
#ifdef _7ZIP_LARGE_PAGES
SIZE_T size = 0;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (largePageMinimum == 0)
return;
size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
#endif
}
void *BigAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
#endif
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
{
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res != 0)
return res;
}
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void BigFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#endif

View File

@ -1,29 +0,0 @@
/* Alloc.h */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include <stddef.h>
void *MyAlloc(size_t size);
void MyFree(void *address);
#ifdef _WIN32
void SetLargePageSize();
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
#else
#define MidAlloc(size) MyAlloc(size)
#define MidFree(address) MyFree(address)
#define BigAlloc(size) MyAlloc(size)
#define BigFree(address) MyFree(address)
#endif
#endif

View File

@ -1,70 +0,0 @@
/* 7zAlloc.c */
#include <stdlib.h>
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
#endif
void *SzAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
g_allocCount++;
#endif
return malloc(size);
}
void SzFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCount--;
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
}
#endif
free(address);
}
void *SzAllocTemp(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
g_allocCountTemp++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
#endif
#endif
return malloc(size);
}
void SzFreeTemp(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCountTemp--;
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
}
#ifdef _WIN32
HeapFree(GetProcessHeap(), 0, address);
return;
#endif
#endif
free(address);
}

View File

@ -1,20 +0,0 @@
/* 7zAlloc.h */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stddef.h>
typedef struct _ISzAlloc
{
void *(*Alloc)(size_t size);
void (*Free)(void *address); /* address can be 0 */
} ISzAlloc;
void *SzAlloc(size_t size);
void SzFree(void *address);
void *SzAllocTemp(size_t size);
void SzFreeTemp(void *address);
#endif

View File

@ -1,29 +0,0 @@
/* 7zBuffer.c */
#include "7zBuffer.h"
#include "7zAlloc.h"
void SzByteBufferInit(CSzByteBuffer *buffer)
{
buffer->Capacity = 0;
buffer->Items = 0;
}
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
{
buffer->Capacity = newCapacity;
if (newCapacity == 0)
{
buffer->Items = 0;
return 1;
}
buffer->Items = (Byte *)allocFunc(newCapacity);
return (buffer->Items != 0);
}
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
{
freeFunc(buffer->Items);
buffer->Items = 0;
buffer->Capacity = 0;
}

View File

@ -1,19 +0,0 @@
/* 7zBuffer.h */
#ifndef __7Z_BUFFER_H
#define __7Z_BUFFER_H
#include <stddef.h>
#include "../../Types.h"
typedef struct _CSzByteBuffer
{
size_t Capacity;
Byte *Items;
}CSzByteBuffer;
void SzByteBufferInit(CSzByteBuffer *buffer);
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
#endif

View File

@ -1,347 +0,0 @@
/* 7zDecode.c */
#include <string.h>
#include "7zDecode.h"
#ifdef _SZ_ONE_DIRECTORY
#include "LzmaDecode.h"
#else
#include "../../Compress/Lzma/LzmaDecode.h"
#include "../../Compress/Branch/BranchX86.h"
#include "../../Compress/Branch/BranchX86_2.h"
#endif
#define k_Copy 0
#define k_LZMA 0x30101
#define k_BCJ 0x03030103
#define k_BCJ2 0x0303011B
#ifdef _LZMA_IN_CB
typedef struct _CLzmaInCallbackImp
{
ILzmaInCallback InCallback;
ISzInStream *InStream;
CFileSize Size;
} CLzmaInCallbackImp;
static
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
{
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
size_t processedSize;
SZ_RESULT res;
size_t curSize = (1 << 20);
if (curSize > cb->Size)
curSize = (size_t)cb->Size;
*size = 0;
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize);
*size = (SizeT)processedSize;
if (processedSize > curSize)
return (int)SZE_FAIL;
cb->Size -= processedSize;
if (res == SZ_OK)
return 0;
return (int)res;
}
#endif
static
SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize,
#ifdef _LZMA_IN_CB
ISzInStream *inStream,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
{
#ifdef _LZMA_IN_CB
CLzmaInCallbackImp lzmaCallback;
#else
SizeT inProcessed;
#endif
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
int result;
SizeT outSizeProcessedLoc;
#ifdef _LZMA_IN_CB
lzmaCallback.Size = inSize;
lzmaCallback.InStream = inStream;
lzmaCallback.InCallback.Read = LzmaReadImp;
#endif
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
(unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK)
return SZE_FAIL;
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return SZE_OUTOFMEMORY;
#ifdef _LZMA_OUT_READ
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
{
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
allocMain->Free(state.Probs);
return SZE_OUTOFMEMORY;
}
}
LzmaDecoderInit(&state);
#endif
result = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&lzmaCallback.InCallback,
#else
inBuffer, (SizeT)inSize, &inProcessed,
#endif
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
allocMain->Free(state.Probs);
#ifdef _LZMA_OUT_READ
allocMain->Free(state.Dictionary);
#endif
if (result == LZMA_RESULT_DATA_ERROR)
return SZE_DATA_ERROR;
if (result != LZMA_RESULT_OK)
return SZE_FAIL;
return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR;
}
#ifdef _LZMA_IN_CB
static
SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
void *inBuffer;
size_t processedSize, curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)(inSize);
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize));
if (processedSize == 0)
return SZE_DATA_ERROR;
if (processedSize > curSize)
return SZE_FAIL;
memcpy(outBuffer, inBuffer, processedSize);
outBuffer += processedSize;
inSize -= processedSize;
}
return SZ_OK;
}
#endif
#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
static
SZ_RESULT CheckSupportedFolder(const CFolder *f)
{
if (f->NumCoders < 1 || f->NumCoders > 4)
return SZE_NOTIMPL;
if (IS_UNSUPPORTED_CODER(f->Coders[0]))
return SZE_NOTIMPL;
if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
return SZE_NOTIMPL;
return SZ_OK;
}
if (f->NumCoders == 2)
{
if (IS_NO_BCJ(f->Coders[1]) ||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
return SZE_NOTIMPL;
return SZ_OK;
}
if (f->NumCoders == 4)
{
if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
IS_NO_BCJ2(f->Coders[3]))
return SZE_NOTIMPL;
if (f->NumPackStreams != 4 ||
f->PackStreams[0] != 2 ||
f->PackStreams[1] != 6 ||
f->PackStreams[2] != 1 ||
f->PackStreams[3] != 0 ||
f->NumBindPairs != 3 ||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
return SZE_NOTIMPL;
return SZ_OK;
}
return SZE_NOTIMPL;
}
static
CFileSize GetSum(const CFileSize *values, UInt32 index)
{
CFileSize sum = 0;
UInt32 i;
for (i = 0; i < index; i++)
sum += values[i];
return sum;
}
static
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *inStream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
Byte *tempBuf[])
{
UInt32 ci;
size_t tempSizes[3] = { 0, 0, 0};
size_t tempSize3 = 0;
Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder));
for (ci = 0; ci < folder->NumCoders; ci++)
{
CCoderInfo *coder = &folder->Coders[ci];
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
{
UInt32 si = 0;
CFileSize offset;
CFileSize inSize;
Byte *outBufCur = outBuffer;
size_t outSizeCur = outSize;
if (folder->NumCoders == 4)
{
UInt32 indices[] = { 3, 2, 0 };
CFileSize unpackSize = folder->UnPackSizes[ci];
si = indices[ci];
if (ci < 2)
{
Byte *temp;
outSizeCur = (size_t)unpackSize;
if (outSizeCur != unpackSize)
return SZE_OUTOFMEMORY;
temp = (Byte *)allocMain->Alloc(outSizeCur);
if (temp == 0 && outSizeCur != 0)
return SZE_OUTOFMEMORY;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize)
return SZE_OUTOFMEMORY;
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (size_t)unpackSize;
}
else
return SZE_NOTIMPL;
}
offset = GetSum(packSizes, si);
inSize = packSizes[si];
#ifdef _LZMA_IN_CB
RINOK(inStream->Seek(inStream, startPos + offset));
#endif
if (coder->MethodID == k_Copy)
{
if (inSize != outSizeCur)
return SZE_DATA_ERROR;
#ifdef _LZMA_IN_CB
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
#else
memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
#endif
}
else
{
SZ_RESULT res = SzDecodeLzma(coder, inSize,
#ifdef _LZMA_IN_CB
inStream,
#else
inBuffer + (size_t)offset,
#endif
outBufCur, outSizeCur, allocMain);
RINOK(res)
}
}
else if (coder->MethodID == k_BCJ)
{
UInt32 state;
if (ci != 1)
return SZE_NOTIMPL;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
}
else if (coder->MethodID == k_BCJ2)
{
CFileSize offset = GetSum(packSizes, 1);
CFileSize s3Size = packSizes[1];
SZ_RESULT res;
if (ci != 3)
return SZE_NOTIMPL;
#ifdef _LZMA_IN_CB
RINOK(inStream->Seek(inStream, startPos + offset));
tempSizes[2] = (size_t)s3Size;
if (tempSizes[2] != s3Size)
return SZE_OUTOFMEMORY;
tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0)
return SZE_OUTOFMEMORY;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res)
#endif
res = x86_2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
#ifdef _LZMA_IN_CB
tempBuf[2], tempSizes[2],
#else
inBuffer + (size_t)offset, (size_t)s3Size,
#endif
outBuffer, outSize);
RINOK(res)
}
else
return SZE_NOTIMPL;
}
return SZ_OK;
}
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *inStream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
{
Byte *tempBuf[3] = { 0, 0, 0};
int i;
SZ_RESULT res = SzDecode2(packSizes, folder,
#ifdef _LZMA_IN_CB
inStream, startPos,
#else
inBuffer,
#endif
outBuffer, outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
allocMain->Free(tempBuf[i]);
return res;
}

View File

@ -1,18 +0,0 @@
/* 7zDecode.h */
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
#include "7zItem.h"
#include "7zAlloc.h"
#include "7zIn.h"
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *stream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
#endif

View File

@ -1,119 +0,0 @@
/* 7zExtract.c */
#include "7zExtract.h"
#include "7zDecode.h"
#include "../../7zCrc.h"
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex,
UInt32 *blockIndex,
Byte **outBuffer,
size_t *outBufferSize,
size_t *offset,
size_t *outSizeProcessed,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
SZ_RESULT res = SZ_OK;
*offset = 0;
*outSizeProcessed = 0;
if (folderIndex == (UInt32)-1)
{
allocMain->Free(*outBuffer);
*blockIndex = folderIndex;
*outBuffer = 0;
*outBufferSize = 0;
return SZ_OK;
}
if (*outBuffer == 0 || *blockIndex != folderIndex)
{
CFolder *folder = db->Database.Folders + folderIndex;
CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
size_t unPackSize = (size_t)unPackSizeSpec;
CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
#ifndef _LZMA_IN_CB
Byte *inBuffer = 0;
size_t processedSize;
CFileSize packSizeSpec;
size_t packSize;
RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
packSize = (size_t)packSizeSpec;
if (packSize != packSizeSpec)
return SZE_OUTOFMEMORY;
#endif
if (unPackSize != unPackSizeSpec)
return SZE_OUTOFMEMORY;
*blockIndex = folderIndex;
allocMain->Free(*outBuffer);
*outBuffer = 0;
RINOK(inStream->Seek(inStream, startOffset));
#ifndef _LZMA_IN_CB
if (packSize != 0)
{
inBuffer = (Byte *)allocTemp->Alloc(packSize);
if (inBuffer == 0)
return SZE_OUTOFMEMORY;
}
res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
if (res == SZ_OK && processedSize != packSize)
res = SZE_FAIL;
#endif
if (res == SZ_OK)
{
*outBufferSize = unPackSize;
if (unPackSize != 0)
{
*outBuffer = (Byte *)allocMain->Alloc(unPackSize);
if (*outBuffer == 0)
res = SZE_OUTOFMEMORY;
}
if (res == SZ_OK)
{
res = SzDecode(db->Database.PackSizes +
db->FolderStartPackStreamIndex[folderIndex], folder,
#ifdef _LZMA_IN_CB
inStream, startOffset,
#else
inBuffer,
#endif
*outBuffer, unPackSize, allocTemp);
if (res == SZ_OK)
{
if (folder->UnPackCRCDefined)
{
if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
res = SZE_CRC_ERROR;
}
}
}
}
#ifndef _LZMA_IN_CB
allocTemp->Free(inBuffer);
#endif
}
if (res == SZ_OK)
{
UInt32 i;
CFileItem *fileItem = db->Database.Files + fileIndex;
*offset = 0;
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
*offset += (UInt32)db->Database.Files[i].Size;
*outSizeProcessed = (size_t)fileItem->Size;
if (*offset + *outSizeProcessed > *outBufferSize)
return SZE_FAIL;
{
if (fileItem->IsFileCRCDefined)
{
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
res = SZE_CRC_ERROR;
}
}
}
return res;
}

View File

@ -1,40 +0,0 @@
/* 7zExtract.h */
#ifndef __7Z_EXTRACT_H
#define __7Z_EXTRACT_H
#include "7zIn.h"
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
#endif

View File

@ -1,5 +0,0 @@
/* 7zHeader.c */
#include "7zHeader.h"
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};

View File

@ -1,55 +0,0 @@
/* 7zHeader.h */
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
#include "../../Types.h"
#define k7zSignatureSize 6
extern Byte k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0
#define k7zStartHeaderSize 0x20
enum EIdEnum
{
k7zIdEnd,
k7zIdHeader,
k7zIdArchiveProperties,
k7zIdAdditionalStreamsInfo,
k7zIdMainStreamsInfo,
k7zIdFilesInfo,
k7zIdPackInfo,
k7zIdUnPackInfo,
k7zIdSubStreamsInfo,
k7zIdSize,
k7zIdCRC,
k7zIdFolder,
k7zIdCodersUnPackSize,
k7zIdNumUnPackStream,
k7zIdEmptyStream,
k7zIdEmptyFile,
k7zIdAnti,
k7zIdName,
k7zIdCreationTime,
k7zIdLastAccessTime,
k7zIdLastWriteTime,
k7zIdWinAttributes,
k7zIdComment,
k7zIdEncodedHeader,
k7zIdStartPos
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +0,0 @@
/* 7zIn.h */
#ifndef __7Z_IN_H
#define __7Z_IN_H
#include "7zHeader.h"
#include "7zItem.h"
#include "7zAlloc.h"
#include "../../Compress/Lzma/LzmaDecode.h"
typedef struct _CInArchiveInfo
{
CFileSize StartPositionAfterHeader;
CFileSize DataStartPosition;
}CInArchiveInfo;
typedef struct _CArchiveDatabaseEx
{
CArchiveDatabase Database;
CInArchiveInfo ArchiveInfo;
UInt32 *FolderStartPackStreamIndex;
CFileSize *PackStreamStartPositions;
UInt32 *FolderStartFileIndex;
UInt32 *FileIndexToFolderIndexMap;
}CArchiveDatabaseEx;
void SzArDbExInit(CArchiveDatabaseEx *db);
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize);
typedef struct _ISzInStream
{
#ifdef _LZMA_IN_CB
SZ_RESULT (*Read)(
void *object, /* pointer to ISzInStream itself */
void **buffer, /* out: pointer to buffer with data */
size_t maxRequiredSize, /* max required size to read */
size_t *processedSize); /* real processed size.
processedSize can be less than maxRequiredSize.
If processedSize == 0, then there are no more
bytes in stream. */
#else
SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
#endif
SZ_RESULT (*Seek)(void *object, CFileSize pos);
} ISzInStream;
int SzArchiveOpen(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
#endif

View File

@ -1,140 +0,0 @@
/* 7zItem.c */
#include "7zItem.h"
#include "7zAlloc.h"
void SzCoderInfoInit(CCoderInfo *coder)
{
SzByteBufferInit(&coder->Properties);
}
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
{
SzByteBufferFree(&coder->Properties, freeFunc);
SzCoderInfoInit(coder);
}
void SzFolderInit(CFolder *folder)
{
folder->NumCoders = 0;
folder->Coders = 0;
folder->NumBindPairs = 0;
folder->BindPairs = 0;
folder->NumPackStreams = 0;
folder->PackStreams = 0;
folder->UnPackSizes = 0;
folder->UnPackCRCDefined = 0;
folder->UnPackCRC = 0;
folder->NumUnPackStreams = 0;
}
static
void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
{
UInt32 i;
if (folder->Coders)
for (i = 0; i < folder->NumCoders; i++)
SzCoderInfoFree(&folder->Coders[i], freeFunc);
freeFunc(folder->Coders);
freeFunc(folder->BindPairs);
freeFunc(folder->PackStreams);
freeFunc(folder->UnPackSizes);
SzFolderInit(folder);
}
UInt32 SzFolderGetNumOutStreams(CFolder *folder)
{
UInt32 result = 0;
UInt32 i;
for (i = 0; i < folder->NumCoders; i++)
result += folder->Coders[i].NumOutStreams;
return result;
}
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
{
UInt32 i;
for(i = 0; i < folder->NumBindPairs; i++)
if (folder->BindPairs[i].InIndex == inStreamIndex)
return i;
return -1;
}
static
int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
{
UInt32 i;
for(i = 0; i < folder->NumBindPairs; i++)
if (folder->BindPairs[i].OutIndex == outStreamIndex)
return i;
return -1;
}
CFileSize SzFolderGetUnPackSize(CFolder *folder)
{
int i = (int)SzFolderGetNumOutStreams(folder);
if (i == 0)
return 0;
for (i--; i >= 0; i--)
if (SzFolderFindBindPairForOutStream(folder, i) < 0)
return folder->UnPackSizes[i];
/* throw 1; */
return 0;
}
/*
int FindPackStreamArrayIndex(int inStreamIndex) const
{
for(int i = 0; i < PackStreams.Size(); i++)
if (PackStreams[i] == inStreamIndex)
return i;
return -1;
}
*/
void SzFileInit(CFileItem *fileItem)
{
fileItem->IsFileCRCDefined = 0;
fileItem->HasStream = 1;
fileItem->IsDirectory = 0;
fileItem->IsAnti = 0;
fileItem->IsLastWriteTimeDefined = 0;
fileItem->Name = 0;
}
static
void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
{
freeFunc(fileItem->Name);
SzFileInit(fileItem);
}
void SzArchiveDatabaseInit(CArchiveDatabase *db)
{
db->NumPackStreams = 0;
db->PackSizes = 0;
db->PackCRCsDefined = 0;
db->PackCRCs = 0;
db->NumFolders = 0;
db->Folders = 0;
db->NumFiles = 0;
db->Files = 0;
}
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
{
UInt32 i;
if (db->Folders)
for (i = 0; i < db->NumFolders; i++)
SzFolderFree(&db->Folders[i], freeFunc);
if (db->Files)
for (i = 0; i < db->NumFiles; i++)
SzFileFree(&db->Files[i], freeFunc);
freeFunc(db->PackSizes);
freeFunc(db->PackCRCsDefined);
freeFunc(db->PackCRCs);
freeFunc(db->Folders);
freeFunc(db->Files);
SzArchiveDatabaseInit(db);
}

View File

@ -1,95 +0,0 @@
/* 7zItem.h */
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
#include "7zMethodID.h"
#include "7zHeader.h"
#include "7zBuffer.h"
typedef struct _CCoderInfo
{
UInt32 NumInStreams;
UInt32 NumOutStreams;
CMethodID MethodID;
CSzByteBuffer Properties;
}CCoderInfo;
void SzCoderInfoInit(CCoderInfo *coder);
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
typedef struct _CBindPair
{
UInt32 InIndex;
UInt32 OutIndex;
}CBindPair;
typedef struct _CFolder
{
UInt32 NumCoders;
CCoderInfo *Coders;
UInt32 NumBindPairs;
CBindPair *BindPairs;
UInt32 NumPackStreams;
UInt32 *PackStreams;
CFileSize *UnPackSizes;
int UnPackCRCDefined;
UInt32 UnPackCRC;
UInt32 NumUnPackStreams;
}CFolder;
void SzFolderInit(CFolder *folder);
CFileSize SzFolderGetUnPackSize(CFolder *folder);
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
/*CFileSize SzFolderGetUnPackSize(CFolder *folder);*/
typedef struct _CArchiveFileTime
{
UInt32 Low;
UInt32 High;
} CArchiveFileTime;
typedef struct _CFileItem
{
CArchiveFileTime LastWriteTime;
/*
CFileSize StartPos;
UInt32 Attributes;
*/
CFileSize Size;
UInt32 FileCRC;
char *Name;
Byte IsFileCRCDefined;
Byte HasStream;
Byte IsDirectory;
Byte IsAnti;
Byte IsLastWriteTimeDefined;
/*
int AreAttributesDefined;
int IsLastWriteTimeDefined;
int IsStartPosDefined;
*/
}CFileItem;
void SzFileInit(CFileItem *fileItem);
typedef struct _CArchiveDatabase
{
UInt32 NumPackStreams;
CFileSize *PackSizes;
Byte *PackCRCsDefined;
UInt32 *PackCRCs;
UInt32 NumFolders;
CFolder *Folders;
UInt32 NumFiles;
CFileItem *Files;
}CArchiveDatabase;
void SzArchiveDatabaseInit(CArchiveDatabase *db);
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
#endif

View File

@ -1,10 +0,0 @@
/* 7zMethodID.c */
#include "7zMethodID.h"
/*
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
{
return (*a1 == *a2) ? 1 : 0;
}
*/

View File

@ -1,10 +0,0 @@
/* 7zMethodID.h */
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
#include "../../Types.h"
typedef UInt64 CMethodID;
#endif

View File

@ -1,51 +0,0 @@
/* BranchTypes.h */
#ifndef __BRANCHTYPES_H
#define __BRANCHTYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
#endif
#endif
#endif
/* #define _LZMA_NO_SYSTEM_SIZE_T */
/* You can use it, if you don't want <stddef.h> */
#ifndef _7ZIP_SIZET_DEFINED
#define _7ZIP_SIZET_DEFINED
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
#endif
#endif

View File

@ -1,84 +0,0 @@
/* BranchX86.c */
#include "BranchX86.h"
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
{
SizeT bufferPos = 0, prevPosT;
UInt32 prevMask = *prevMaskMix & 0x7;
if (endPos < 5)
return 0;
nowPos += 5;
prevPosT = (SizeT)0 - 1;
for(;;)
{
Byte *p = buffer + bufferPos;
Byte *limit = buffer + endPos - 4;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
bufferPos = (SizeT)(p - buffer);
if (p >= limit)
break;
prevPosT = bufferPos - prevPosT;
if (prevPosT > 3)
prevMask = 0;
else
{
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
if (prevMask != 0)
{
Byte b = p[4 - kMaskToBitNumber[prevMask]];
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
{
prevPosT = bufferPos;
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
continue;
}
}
}
prevPosT = bufferPos;
if (Test86MSByte(p[4]))
{
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 dest;
for (;;)
{
Byte b;
int index;
if (encoding)
dest = (nowPos + (UInt32)bufferPos) + src;
else
dest = src - (nowPos + (UInt32)bufferPos);
if (prevMask == 0)
break;
index = kMaskToBitNumber[prevMask] * 8;
b = (Byte)(dest >> (24 - index));
if (!Test86MSByte(b))
break;
src = dest ^ ((1 << (32 - index)) - 1);
}
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
p[3] = (Byte)(dest >> 16);
p[2] = (Byte)(dest >> 8);
p[1] = (Byte)dest;
bufferPos += 5;
}
else
{
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
}
}
prevPosT = bufferPos - prevPosT;
*prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
}

View File

@ -1,12 +0,0 @@
/* BranchX86.h */
#ifndef __BRANCHX86_H
#define __BRANCHX86_H
#include "BranchTypes.h"
#define x86_Convert_Init(state) { state = 0; }
SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
#endif

View File

@ -1,135 +0,0 @@
/* BranchX86_2.c */
#include "BranchX86_2.h"
#include "../../Alloc.h"
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
/* #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits)); */
/* #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits)); */
int x86_2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
{
CProb p[256 + 2];
SizeT inPos = 0, outPos = 0;
const Byte *Buffer, *BufferLim;
UInt32 Range, Code;
Byte prevByte = 0;
unsigned int i;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
p[i] = kBitModelTotal >> 1;
RC_INIT(buf3, size3);
if (outSize == 0)
return BCJ2_RESULT_OK;
for (;;)
{
Byte b;
CProb *prob;
UInt32 bound;
SizeT limit = size0 - inPos;
if (outSize - outPos < limit)
limit = outSize - outPos;
while (limit != 0)
{
Byte b = buf0[inPos];
outBuf[outPos++] = b;
if (IsJ(prevByte, b))
break;
inPos++;
prevByte = b;
limit--;
}
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IfBit0(prob)
{
UpdateBit0(prob)
prevByte = b;
}
else
{
UInt32 dest;
const Byte *v;
UpdateBit1(prob)
if (b == 0xE8)
{
v = buf1;
if (size1 < 4)
return BCJ2_RESULT_DATA_ERROR;
buf1 += 4;
size1 -= 4;
}
else
{
v = buf2;
if (size2 < 4)
return BCJ2_RESULT_DATA_ERROR;
buf2 += 4;
size2 -= 4;
}
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest;
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 8);
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
}
}
return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
}

View File

@ -1,28 +0,0 @@
/* BranchX86_2.h */
#ifndef __BRANCHX86_2_H
#define __BRANCHX86_2_H
#include "BranchTypes.h"
#define BCJ2_RESULT_OK 0
#define BCJ2_RESULT_DATA_ERROR 1
/*
Conditions:
outSize <= FullOutputSize,
where FullOutputSize is full size of output stream of x86_2 filter.
If buf0 overlaps outBuf, there are two required conditions:
1) (buf0 >= outBuf)
2) (buf0 + size0 >= outBuf + FullOutputSize).
*/
int x86_2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize);
#endif

View File

@ -1,584 +0,0 @@
/*
LzmaDecode.c
LZMA Decoder (optimized for Speed version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
#ifdef _LZMA_IN_CB
#define RC_TEST { if (Buffer == BufferLim) \
{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
#else
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
#endif
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)) ;
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9) ;
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
#ifdef _LZMA_OUT_READ
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
}
#endif
return LZMA_RESULT_OK;
}
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{
CProb *p = vs->Probs;
SizeT nowPos = 0;
Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
#ifdef _LZMA_OUT_READ
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
#ifdef _LZMA_IN_CB
const Byte *Buffer = vs->Buffer;
const Byte *BufferLim = vs->BufferLim;
#else
const Byte *Buffer = inStream;
const Byte *BufferLim = inStream + inSize;
#endif
int state = vs->State;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4];
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
#else /* if !_LZMA_OUT_READ */
int state = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
int len = 0;
const Byte *Buffer;
const Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
#endif /* _LZMA_OUT_READ */
while(nowPos < outSize)
{
CProb *prob;
UInt32 bound;
int posState = (int)(
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
(((
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
#else
matchByte = outStream[nowPos - rep0];
#endif
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (Byte)symbol;
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
#ifdef _LZMA_OUT_READ
UInt32 pos;
#endif
UpdateBit0(prob);
#ifdef _LZMA_OUT_READ
if (distanceLimit == 0)
#else
if (nowPos == 0)
#endif
return LZMA_RESULT_DATA_ERROR;
state = state < kNumLitStates ? 9 : 11;
#ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
RC_NORMALIZE;
#ifdef _LZMA_OUT_READ
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
#endif
#ifdef _LZMA_IN_CB
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
#else
*inSizeProcessed = (SizeT)(Buffer - inStream);
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -1,113 +0,0 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMADECODE_H
#define __LZMADECODE_H
#include "LzmaTypes.h"
#define _LZMA_IN_CB
/* Use callback for input data */
/* #define _LZMA_OUT_READ */
/* Use read function for output data */
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_LOC_OPT */
/* Enable local speed optimizations inside code */
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback
{
int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
} ILzmaInCallback;
#endif
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
#ifdef _LZMA_OUT_READ
UInt32 DictionarySize;
#endif
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
#ifdef _LZMA_IN_CB
const unsigned char *Buffer;
const unsigned char *BufferLim;
#endif
#ifdef _LZMA_OUT_READ
unsigned char *Dictionary;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen;
unsigned char TempDictionary[4];
#endif
} CLzmaDecoderState;
#ifdef _LZMA_OUT_READ
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
#endif
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
#endif

View File

@ -1,45 +0,0 @@
/*
LzmaTypes.h
Types for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.40 (2006-05-01)
*/
#ifndef __LZMATYPES_H
#define __LZMATYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
/* #define _LZMA_NO_SYSTEM_SIZE_T */
/* You can use it, if you don't want <stddef.h> */
#ifndef _7ZIP_SIZET_DEFINED
#define _7ZIP_SIZET_DEFINED
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
#endif
#endif

View File

@ -1,100 +0,0 @@
/* 7zTypes.h */
#ifndef __C_TYPES_H
#define __C_TYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
#ifndef _7ZIP_INT32_DEFINED
#define _7ZIP_INT32_DEFINED
#ifdef _LZMA_INT32_IS_ULONG
typedef long Int32;
#else
typedef int Int32;
#endif
#endif
/* #define _SZ_NO_INT_64 */
/* define it your compiler doesn't support long long int */
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
#endif
#endif
#endif
/* #define _SZ_FILE_SIZE_32 */
/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
#ifndef CFileSize
#ifdef _SZ_FILE_SIZE_32
typedef UInt32 CFileSize;
#else
typedef UInt64 CFileSize;
#endif
#endif
#define SZ_RESULT int
typedef int HRes;
#define RES_OK (0)
#define SZ_OK (0)
#define SZE_DATA_ERROR (1)
#define SZE_CRC_ERROR (3)
#define SZE_ARCHIVE_ERROR (6)
#define SZE_OUTOFMEMORY (0x8007000EL)
#define SZE_NOTIMPL (0x80004001L)
#define SZE_FAIL (0x80004005L)
#define SZE_INVALIDARG (0x80070057L)
#ifndef RINOK
#define RINOK(x) { HRes __result_ = (x); if(__result_ != 0) return __result_; }
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _MSC_VER
#define StdCall __stdcall
#else
#define StdCall
#endif
#if _MSC_VER >= 1300
#define MY_FAST_CALL __declspec(noinline) __fastcall
#elif defined( _MSC_VER)
#define MY_FAST_CALL __fastcall
#else
#define MY_FAST_CALL
#endif
#endif

View File

@ -1,19 +0,0 @@
Changes to 7z_C source
----------------------
I made several minor changes:
* Enabled _LZMA_IN_CB in LzmaDecoer.h and fixed other files that depend
on this setting to properly #include this file
* Fixed several memory free functions to not access NULL when cleaning
up after a failed allocation.
* Made private functions static.
* Fixed SzArchiveOpen to properly report error when header can't be
read.
* Fixed glaring conflicts between LzmaTypes.h and 7zTypes.h.
--
Shay Green <gblargg@gmail.com>

View File

@ -1,663 +0,0 @@
LZMA SDK 4.57
-------------
LZMA SDK Copyright (C) 1999-2007 Igor Pavlov
LZMA SDK provides the documentation, samples, header files, libraries,
and tools you need to develop applications that use LZMA compression.
LZMA is default and general compression method of 7z format
in 7-Zip compression program (www.7-zip.org). LZMA provides high
compression ratio and very fast decompression.
LZMA is an improved version of famous LZ77 compression algorithm.
It was improved in way of maximum increasing of compression ratio,
keeping high decompression speed and low memory requirements for
decompressing.
LICENSE
-------
LZMA SDK is available under any of the following licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
4) Proprietary license
It means that you can select one of these four options and follow rules of that license.
1,2) GNU LGPL and CPL licenses are pretty similar and both these
licenses are classified as
- "Free software licenses" at http://www.gnu.org/
- "OSI-approved" at http://www.opensource.org/
3) SPECIAL EXCEPTION
Igor Pavlov, as the author of this code, expressly permits you
to statically or dynamically link your code (or bind by name)
to the files from LZMA SDK without subjecting your linked
code to the terms of the CPL or GNU LGPL.
Any modifications or additions to files from LZMA SDK, however,
are subject to the GNU LGPL or CPL terms.
SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
while you keep LZMA SDK code unmodified.
SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits
you to use this code under the same terms and conditions contained in the License
Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov.
SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version
of LZMA SDK as update for previous versions.
SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
you to use code of the following files:
BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp,
LzmaAlone.cs, LzmaAlone.java
as public domain code.
4) Proprietary license
LZMA SDK also can be available under a proprietary license which
can include:
1) Right to modify code without subjecting modified code to the
terms of the CPL or GNU LGPL
2) Technical support for code
To request such proprietary license or any additional consultations,
send email message from that page:
http://www.7-zip.org/support.html
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the Common Public License
along with this library.
LZMA SDK Contents
-----------------
LZMA SDK includes:
- C++ source code of LZMA compressing and decompressing
- ANSI-C compatible source code for LZMA decompressing
- C# source code for LZMA compressing and decompressing
- Java source code for LZMA compressing and decompressing
- Compiled file->file LZMA compressing/decompressing program for Windows system
ANSI-C LZMA decompression code was ported from original C++ sources to C.
Also it was simplified and optimized for code size.
But it is fully compatible with LZMA from 7-Zip.
UNIX/Linux version
------------------
To compile C++ version of file->file LZMA, go to directory
C/7zip/Compress/LZMA_Alone
and type "make" or "make clean all" to recompile all.
In some UNIX/Linux versions you must compile LZMA with static libraries.
To compile with static libraries, change string in makefile
LIB = -lm
to string
LIB = -lm -static
Files
---------------------
C - C source code
CPP - CPP source code
CS - C# source code
Java - Java source code
lzma.txt - LZMA SDK description (this file)
7zFormat.txt - 7z Format description
7zC.txt - 7z ANSI-C Decoder description (this file)
methods.txt - Compression method IDs for .7z
LGPL.txt - GNU Lesser General Public License
CPL.html - Common Public License
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
history.txt - history of the LZMA SDK
Source code structure
---------------------
C - C files
Compress - files related to compression/decompression
Lz - files related to LZ (Lempel-Ziv) compression algorithm
Lzma - ANSI-C compatible LZMA decompressor
LzmaDecode.h - interface for LZMA decoding on ANSI-C
LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version)
LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version)
LzmaTest.c - test application that decodes LZMA encoded file
LzmaTypes.h - basic types for LZMA Decoder
LzmaStateDecode.h - interface for LZMA decoding (State version)
LzmaStateDecode.c - LZMA decoding on ANSI-C (State version)
LzmaStateTest.c - test application (State version)
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
Archive - files related to archiving
7z_C - 7z ANSI-C Decoder
CPP -- CPP files
Common - common files for C++ projects
Windows - common files for Windows related code
7zip - files related to 7-Zip Project
Common - common files for 7-Zip
Compress - files related to compression/decompression
LZ - files related to LZ (Lempel-Ziv) compression algorithm
Copy - Copy coder
RangeCoder - Range Coder (special code of compression/decompression)
LZMA - LZMA compression/decompression on C++
LZMA_Alone - file->file LZMA compression/decompression
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
Archive - files related to archiving
Common - common files for archive handling
7z - 7z C++ Encoder/Decoder
Bundles - Modules that are bundles of other modules
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
UI - User Interface files
Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
Common - Common UI files
Console - Code for console archiver
CS - C# files
7zip
Common - some common files for 7-Zip
Compress - files related to compression/decompression
LZ - files related to LZ (Lempel-Ziv) compression algorithm
LZMA - LZMA compression/decompression
LzmaAlone - file->file LZMA compression/decompression
RangeCoder - Range Coder (special code of compression/decompression)
Java - Java files
SevenZip
Compression - files related to compression/decompression
LZ - files related to LZ (Lempel-Ziv) compression algorithm
LZMA - LZMA compression/decompression
RangeCoder - Range Coder (special code of compression/decompression)
C/C++ source code of LZMA SDK is part of 7-Zip project.
You can find ANSI-C LZMA decompressing code at folder
C/7zip/Compress/Lzma
7-Zip doesn't use that ANSI-C LZMA code and that code was developed
specially for this SDK. And files from C/7zip/Compress/Lzma do not need
files from other directories of SDK for compiling.
7-Zip source code can be downloaded from 7-Zip's SourceForge page:
http://sourceforge.net/projects/sevenzip/
LZMA features
-------------
- Variable dictionary size (up to 1 GB)
- Estimated compressing speed: about 1 MB/s on 1 GHz CPU
- Estimated decompressing speed:
- 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon
- 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC
- Small memory requirements for decompressing (8-32 KB + DictionarySize)
- Small code size for decompressing: 2-8 KB (depending from
speed optimizations)
LZMA decoder uses only integer operations and can be
implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
Some critical operations that affect to speed of LZMA decompression:
1) 32*16 bit integer multiply
2) Misspredicted branches (penalty mostly depends from pipeline length)
3) 32-bit shift and arithmetic operations
Speed of LZMA decompressing mostly depends from CPU speed.
Memory speed has no big meaning. But if your CPU has small data cache,
overall weight of memory speed will slightly increase.
How To Use
----------
Using LZMA encoder/decoder executable
--------------------------------------
Usage: LZMA <e|d> inputFile outputFile [<switches>...]
e: encode file
d: decode file
b: Benchmark. There are two tests: compressing and decompressing
with LZMA method. Benchmark shows rating in MIPS (million
instructions per second). Rating value is calculated from
measured speed and it is normalized with AMD Athlon 64 X2 CPU
results. Also Benchmark checks possible hardware errors (RAM
errors in most cases). Benchmark uses these settings:
(-a1, -d21, -fb32, -mfbt4). You can change only -d. Also you
can change number of iterations. Example for 30 iterations:
LZMA b 30
Default number of iterations is 10.
<Switches>
-a{N}: set compression mode 0 = fast, 1 = normal
default: 1 (normal)
d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
The maximum value for dictionary size is 1 GB = 2^30 bytes.
Dictionary size is calculated as DictionarySize = 2^N bytes.
For decompressing file compressed by LZMA method with dictionary
size D = 2^N you need about D bytes of memory (RAM).
-fb{N}: set number of fast bytes - [5, 273], default: 128
Usually big number gives a little bit better compression ratio
and slower compression process.
-lc{N}: set number of literal context bits - [0, 8], default: 3
Sometimes lc=4 gives gain for big files.
-lp{N}: set number of literal pos bits - [0, 4], default: 0
lp switch is intended for periodical data when period is
equal 2^N. For example, for 32-bit (4 bytes)
periodical data you can use lp=2. Often it's better to set lc0,
if you change lp switch.
-pb{N}: set number of pos bits - [0, 4], default: 2
pb switch is intended for periodical data
when period is equal 2^N.
-mf{MF_ID}: set Match Finder. Default: bt4.
Algorithms from hc* group doesn't provide good compression
ratio, but they often works pretty fast in combination with
fast mode (-a0).
Memory requirements depend from dictionary size
(parameter "d" in table below).
MF_ID Memory Description
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
-eos: write End Of Stream marker. By default LZMA doesn't write
eos marker, since LZMA decoder knows uncompressed size
stored in .lzma file header.
-si: Read data from stdin (it will write End Of Stream marker).
-so: Write data to stdout
Examples:
1) LZMA e file.bin file.lzma -d16 -lc0
compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
and 0 literal context bits. -lc0 allows to reduce memory requirements
for decompression.
2) LZMA e file.bin file.lzma -lc0 -lp2
compresses file.bin to file.lzma with settings suitable
for 32-bit periodical data (for example, ARM or MIPS code).
3) LZMA d file.lzma file.bin
decompresses file.lzma to file.bin.
Compression ratio hints
-----------------------
Recommendations
---------------
To increase compression ratio for LZMA compressing it's desirable
to have aligned data (if it's possible) and also it's desirable to locate
data in such order, where code is grouped in one place and data is
grouped in other place (it's better than such mixing: code, data, code,
data, ...).
Using Filters
-------------
You can increase compression ratio for some data types, using
special filters before compressing. For example, it's possible to
increase compression ratio on 5-10% for code for those CPU ISAs:
x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
You can find C/C++ source code of such filters in folder "7zip/Compress/Branch"
You can check compression ratio gain of these filters with such
7-Zip commands (example for ARM code):
No filter:
7z a a1.7z a.bin -m0=lzma
With filter for little-endian ARM code:
7z a a2.7z a.bin -m0=bc_arm -m1=lzma
With filter for big-endian ARM code (using additional Swap4 filter):
7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma
It works in such manner:
Compressing = Filter_encoding + LZMA_encoding
Decompressing = LZMA_decoding + Filter_decoding
Compressing and decompressing speed of such filters is very high,
so it will not increase decompressing time too much.
Moreover, it reduces decompression time for LZMA_decoding,
since compression ratio with filtering is higher.
These filters convert CALL (calling procedure) instructions
from relative offsets to absolute addresses, so such data becomes more
compressible. Source code of these CALL filters is pretty simple
(about 20 lines of C++), so you can convert it from C++ version yourself.
For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
LZMA compressed file format
---------------------------
Offset Size Description
0 1 Special LZMA properties for compressed data
1 4 Dictionary size (little endian)
5 8 Uncompressed size (little endian). -1 means unknown size
13 Compressed data
ANSI-C LZMA Decoder
~~~~~~~~~~~~~~~~~~~
To compile ANSI-C LZMA Decoder you can use one of the following files sets:
1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c (fastest version)
2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c (old size-optimized version)
3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c (zlib-like interface)
Memory requirements for LZMA decoding
-------------------------------------
LZMA decoder doesn't allocate memory itself, so you must
allocate memory and send it to LZMA.
Stack usage of LZMA decoding function for local variables is not
larger than 200 bytes.
How To decompress data
----------------------
LZMA Decoder (ANSI-C version) now supports 5 interfaces:
1) Single-call Decompressing
2) Single-call Decompressing with input stream callback
3) Multi-call Decompressing with output buffer
4) Multi-call Decompressing with input callback and output buffer
5) Multi-call State Decompressing (zlib-like interface)
Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions.
Decompressing steps
-------------------
1) read LZMA properties (5 bytes):
unsigned char properties[LZMA_PROPERTIES_SIZE];
2) read uncompressed size (8 bytes, little-endian)
3) Decode properties:
CLzmaDecoderState state; /* it's 24-140 bytes structure, if int is 32-bit */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
4) Allocate memory block for internal Structures:
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return PrintError(rs, kCantAllocateMessage);
LZMA decoder uses array of CProb variables as internal structure.
By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make
it unsigned_int. It can increase speed on some 32-bit CPUs, but memory
usage will be doubled in that case.
5) Main Decompressing
You must use one of the following interfaces:
5.1 Single-call Decompressing
-----------------------------
When to use: RAM->RAM decompressing
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: no defines
Memory Requirements:
- Input buffer: compressed size
- Output buffer: uncompressed size
- LZMA Internal Structures (~16 KB for default settings)
Interface:
int res = LzmaDecode(&state,
inStream, compressedSize, &inProcessed,
outStream, outSize, &outProcessed);
5.2 Single-call Decompressing with input stream callback
--------------------------------------------------------
When to use: File->RAM or Flash->RAM decompressing.
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: _LZMA_IN_CB
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Output buffer: uncompressed size
- LZMA Internal Structures (~16 KB for default settings)
Interface:
typedef struct _CBuffer
{
ILzmaInCallback InCallback;
FILE *File;
unsigned char Buffer[kInBufferSize];
} CBuffer;
int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
{
CBuffer *bo = (CBuffer *)object;
*buffer = bo->Buffer;
*size = MyReadFile(bo->File, bo->Buffer, kInBufferSize);
return LZMA_RESULT_OK;
}
CBuffer g_InBuffer;
g_InBuffer.File = inFile;
g_InBuffer.InCallback.Read = LzmaReadCompressed;
int res = LzmaDecode(&state,
&g_InBuffer.InCallback,
outStream, outSize, &outProcessed);
5.3 Multi-call decompressing with output buffer
-----------------------------------------------
When to use: RAM->File decompressing
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: _LZMA_OUT_READ
Memory Requirements:
- Input buffer: compressed size
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures (~16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in stream properties)
Interface:
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
LzmaDecoderInit(&state);
do
{
LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed);
inAvail -= inProcessed;
inBuffer += inProcessed;
}
while you need more bytes
see LzmaTest.c for more details.
5.4 Multi-call decompressing with input callback and output buffer
------------------------------------------------------------------
When to use: File->File decompressing
Compile files: LzmaDecode.h, LzmaDecode.c
Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures (~16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in stream properties)
Interface:
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
LzmaDecoderInit(&state);
do
{
LzmaDecode(&state,
&bo.InCallback,
g_OutBuffer, outAvail, &outProcessed);
}
while you need more bytes
see LzmaTest.c for more details:
5.5 Multi-call State Decompressing (zlib-like interface)
------------------------------------------------------------------
When to use: file->file decompressing
Compile files: LzmaStateDecode.h, LzmaStateDecode.c
Compile defines:
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures (~16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in stream properties)
Interface:
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
LzmaDecoderInit(&state);
do
{
res = LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed,
finishDecoding);
inAvail -= inProcessed;
inBuffer += inProcessed;
}
while you need more bytes
see LzmaStateTest.c for more details:
6) Free all allocated blocks
Note
----
LzmaDecodeSize.c is size-optimized version of LzmaDecode.c.
But compiled code of LzmaDecodeSize.c can be larger than
compiled code of LzmaDecode.c. So it's better to use
LzmaDecode.c in most cases.
EXIT codes
-----------
LZMA decoder can return one of the following codes:
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
If you use callback function for input data and you return some
error code, LZMA Decoder also returns that code.
LZMA Defines
------------
_LZMA_IN_CB - Use callback for input data
_LZMA_OUT_READ - Use read function for output data
_LZMA_LOC_OPT - Enable local speed optimizations inside code.
_LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version).
_LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version)
and LzmaStateDecode.c
_LZMA_PROB32 - It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler
and long is 32-bit.
_LZMA_SYSTEM_SIZE_T - Define it if you want to use system's size_t.
You can use it to enable 64-bit sizes supporting
C++ LZMA Encoder/Decoder
~~~~~~~~~~~~~~~~~~~~~~~~
C++ LZMA code use COM-like interfaces. So if you want to use it,
you can study basics of COM/OLE.
By default, LZMA Encoder contains all Match Finders.
But for compressing it's enough to have just one of them.
So for reducing size of compressing code you can define:
#define COMPRESS_MF_BT
#define COMPRESS_MF_BT4
and it will use only bt4 match finder.
---
http://www.7-zip.org
http://www.7-zip.org/support.html

View File

@ -1,26 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "File_Extractor.vcproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.ActiveCfg = Debug|x64
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|x64.Build.0 = Debug|x64
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.ActiveCfg = Release|x64
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,537 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="File_Extractor"
ProjectGUID="{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
RootNamespace="File_Extractor"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="2"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\zlib"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="2"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\zlib"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\zlib"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\zlib"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<Filter
Name="fex"
>
<File
RelativePath=".\fex\abstract_file.cpp"
>
</File>
<File
RelativePath=".\fex\Data_Reader.cpp"
>
</File>
<File
RelativePath=".\fex\fex.cpp"
>
</File>
<File
RelativePath=".\fex\File_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Gzip_Reader.cpp"
>
</File>
<File
RelativePath=".\fex\Single_File_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\unzip.cpp"
>
</File>
<File
RelativePath=".\fex\Zip7_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Zip_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Zlib_Inflater.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<Filter
Name="fex"
>
<File
RelativePath=".\fex\abstract_file.h"
>
</File>
<File
RelativePath=".\fex\blargg_common.h"
>
</File>
<File
RelativePath=".\fex\blargg_config.h"
>
</File>
<File
RelativePath=".\fex\blargg_endian.h"
>
</File>
<File
RelativePath=".\fex\blargg_source.h"
>
</File>
<File
RelativePath=".\fex\Data_Reader.h"
>
</File>
<File
RelativePath=".\fex\fex.h"
>
</File>
<File
RelativePath=".\fex\File_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Gzip_Reader.h"
>
</File>
<File
RelativePath=".\fex\Single_File_Extractor.h"
>
</File>
<File
RelativePath=".\fex\unzip.h"
>
</File>
<File
RelativePath=".\fex\Zip7_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Zip_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Zlib_Inflater.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="7z_C"
>
<File
RelativePath=".\7z_C\7zCrc.c"
>
</File>
<File
RelativePath=".\7z_C\7zCrc.h"
>
</File>
<File
RelativePath=".\7z_C\Alloc.c"
>
</File>
<File
RelativePath=".\7z_C\Alloc.h"
>
</File>
<File
RelativePath=".\7z_C\Types.h"
>
</File>
<Filter
Name="Compress"
>
<Filter
Name="Branch"
>
<File
RelativePath=".\7z_C\Compress\Branch\BranchTypes.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86_2.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86_2.h"
>
</File>
</Filter>
<Filter
Name="Lzma"
>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaDecode.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaDecode.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaTypes.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Archive"
>
<Filter
Name="7z"
>
<File
RelativePath=".\7z_C\Archive\7z\7zAlloc.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zAlloc.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zBuffer.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zBuffer.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zDecode.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zDecode.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zExtract.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zExtract.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zHeader.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zHeader.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zIn.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zIn.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zItem.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zItem.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zMethodID.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zMethodID.h"
>
</File>
</Filter>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,387 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="File_Extractor"
ProjectGUID="{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
RootNamespace="File_Extractor"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="0"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(ProjectDir)..\zlib&quot;"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)_temp"
ConfigurationType="4"
CharacterSet="0"
WholeProgramOptimization="1"
BuildLogFile="$(IntDir)\$(ProjectName)_BuildLog.htm"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(ProjectDir)..\zlib&quot;"
PreprocessorDefinitions="FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="fex"
>
<File
RelativePath=".\fex\abstract_file.cpp"
>
</File>
<File
RelativePath=".\fex\abstract_file.h"
>
</File>
<File
RelativePath=".\fex\blargg_common.h"
>
</File>
<File
RelativePath=".\fex\blargg_config.h"
>
</File>
<File
RelativePath=".\fex\blargg_endian.h"
>
</File>
<File
RelativePath=".\fex\blargg_source.h"
>
</File>
<File
RelativePath=".\fex\Data_Reader.cpp"
>
</File>
<File
RelativePath=".\fex\Data_Reader.h"
>
</File>
<File
RelativePath=".\fex\fex.cpp"
>
</File>
<File
RelativePath=".\fex\fex.h"
>
</File>
<File
RelativePath=".\fex\File_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\File_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Gzip_Reader.cpp"
>
</File>
<File
RelativePath=".\fex\Gzip_Reader.h"
>
</File>
<File
RelativePath=".\fex\Single_File_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Single_File_Extractor.h"
>
</File>
<File
RelativePath=".\fex\unzip.cpp"
>
</File>
<File
RelativePath=".\fex\unzip.h"
>
</File>
<File
RelativePath=".\fex\Zip7_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Zip7_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Zip_Extractor.cpp"
>
</File>
<File
RelativePath=".\fex\Zip_Extractor.h"
>
</File>
<File
RelativePath=".\fex\Zlib_Inflater.cpp"
>
</File>
<File
RelativePath=".\fex\Zlib_Inflater.h"
>
</File>
</Filter>
<Filter
Name="7z"
>
<File
RelativePath=".\7z_C\7zC.txt"
>
</File>
<File
RelativePath=".\7z_C\7zCrc.c"
>
</File>
<File
RelativePath=".\7z_C\7zCrc.h"
>
</File>
<File
RelativePath=".\7z_C\Alloc.c"
>
</File>
<File
RelativePath=".\7z_C\Alloc.h"
>
</File>
<File
RelativePath=".\7z_C\changes.txt"
>
</File>
<File
RelativePath=".\7z_C\lzma.txt"
>
</File>
<File
RelativePath=".\7z_C\Types.h"
>
</File>
<Filter
Name="Archive"
>
<File
RelativePath=".\7z_C\Archive\7z\7zAlloc.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zAlloc.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zBuffer.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zBuffer.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zDecode.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zDecode.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zExtract.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zExtract.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zHeader.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zHeader.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zIn.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zIn.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zItem.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zItem.h"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zMethodID.c"
>
</File>
<File
RelativePath=".\7z_C\Archive\7z\7zMethodID.h"
>
</File>
</Filter>
<Filter
Name="Compress"
>
<File
RelativePath=".\7z_C\Compress\Branch\BranchTypes.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86_2.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Branch\BranchX86_2.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaDecode.c"
>
</File>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaDecode.h"
>
</File>
<File
RelativePath=".\7z_C\Compress\Lzma\LzmaTypes.h"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="9.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="GOLIATH"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="GOLIATH"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "File_Extractor2010.vcxproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,147 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>File_Extractor</ProjectName>
<ProjectGuid>{7AEC599C-7C82-4F00-AA60-411E0A359CB0}</ProjectGuid>
<RootNamespace>File_Extractor</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<BuildLogFile>$(IntDir)$(ProjectName)_BuildLog.htm</BuildLogFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<BuildLogFile>$(IntDir)$(ProjectName)_BuildLog.htm</BuildLogFile>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<ExecutablePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);d:\Projects\Dev-Cpp\bin\;</ExecutablePath>
<ExecutablePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);d:\Projects\Dev-Cpp\bin\;</ExecutablePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;d:\Projects\dependencies\zlib\;c:\Program Files (x86)\Microsoft DirectX SDK (August 2009)\Include\;d:\Projects\dependencies\libpng\;c:\Program Files (x86)\OpenAL 1.1 SDK\include\;</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;d:\Projects\dependencies\zlib\;c:\Program Files (x86)\Microsoft DirectX SDK (August 2009)\Include\;d:\Projects\dependencies\libpng\;c:\Program Files (x86)\OpenAL 1.1 SDK\include\;</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib;c:\Program Files (x86)\Microsoft DirectX SDK (August 2009)\Lib\x86\;c:\Program Files (x86)\OpenAL 1.1 SDK\libs\;d:\Projects\dependencies\libs\;</LibraryPath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib;c:\Program Files (x86)\Microsoft DirectX SDK (August 2009)\Lib\x86\;c:\Program Files (x86)\OpenAL 1.1 SDK\libs\;d:\Projects\dependencies\libs\;</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>FEX_ENABLE_RAR;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Full</Optimization>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="fex\abstract_file.cpp" />
<ClCompile Include="fex\Data_Reader.cpp" />
<ClCompile Include="fex\fex.cpp" />
<ClCompile Include="fex\File_Extractor.cpp" />
<ClCompile Include="fex\Gzip_Reader.cpp" />
<ClCompile Include="fex\Single_File_Extractor.cpp" />
<ClCompile Include="fex\unzip.cpp" />
<ClCompile Include="fex\Zip7_Extractor.cpp" />
<ClCompile Include="fex\Zip_Extractor.cpp" />
<ClCompile Include="fex\Zlib_Inflater.cpp" />
<ClCompile Include="7z_C\7zCrc.c" />
<ClCompile Include="7z_C\Alloc.c" />
<ClCompile Include="7z_C\Archive\7z\7zAlloc.c" />
<ClCompile Include="7z_C\Archive\7z\7zBuffer.c" />
<ClCompile Include="7z_C\Archive\7z\7zDecode.c" />
<ClCompile Include="7z_C\Archive\7z\7zExtract.c" />
<ClCompile Include="7z_C\Archive\7z\7zHeader.c" />
<ClCompile Include="7z_C\Archive\7z\7zIn.c" />
<ClCompile Include="7z_C\Archive\7z\7zItem.c" />
<ClCompile Include="7z_C\Archive\7z\7zMethodID.c" />
<ClCompile Include="7z_C\Compress\Branch\BranchX86.c" />
<ClCompile Include="7z_C\Compress\Branch\BranchX86_2.c" />
<ClCompile Include="7z_C\Compress\Lzma\LzmaDecode.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="fex\abstract_file.h" />
<ClInclude Include="fex\blargg_common.h" />
<ClInclude Include="fex\blargg_config.h" />
<ClInclude Include="fex\blargg_endian.h" />
<ClInclude Include="fex\blargg_source.h" />
<ClInclude Include="fex\Data_Reader.h" />
<ClInclude Include="fex\fex.h" />
<ClInclude Include="fex\File_Extractor.h" />
<ClInclude Include="fex\Gzip_Reader.h" />
<ClInclude Include="fex\Single_File_Extractor.h" />
<ClInclude Include="fex\unzip.h" />
<ClInclude Include="fex\Zip7_Extractor.h" />
<ClInclude Include="fex\Zip_Extractor.h" />
<ClInclude Include="fex\Zlib_Inflater.h" />
<ClInclude Include="7z_C\7zCrc.h" />
<ClInclude Include="7z_C\Alloc.h" />
<ClInclude Include="7z_C\Types.h" />
<ClInclude Include="7z_C\Archive\7z\7zAlloc.h" />
<ClInclude Include="7z_C\Archive\7z\7zBuffer.h" />
<ClInclude Include="7z_C\Archive\7z\7zDecode.h" />
<ClInclude Include="7z_C\Archive\7z\7zExtract.h" />
<ClInclude Include="7z_C\Archive\7z\7zHeader.h" />
<ClInclude Include="7z_C\Archive\7z\7zIn.h" />
<ClInclude Include="7z_C\Archive\7z\7zItem.h" />
<ClInclude Include="7z_C\Archive\7z\7zMethodID.h" />
<ClInclude Include="7z_C\Compress\Branch\BranchTypes.h" />
<ClInclude Include="7z_C\Compress\Branch\BranchX86.h" />
<ClInclude Include="7z_C\Compress\Branch\BranchX86_2.h" />
<ClInclude Include="7z_C\Compress\Lzma\LzmaDecode.h" />
<ClInclude Include="7z_C\Compress\Lzma\LzmaTypes.h" />
</ItemGroup>
<ItemGroup>
<None Include="7z_C\7zC.txt" />
<None Include="7z_C\changes.txt" />
<None Include="7z_C\lzma.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,191 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="7z">
<UniqueIdentifier>{389faf79-0326-47e9-957c-9a482f94e2e2}</UniqueIdentifier>
</Filter>
<Filter Include="7z\Archive">
<UniqueIdentifier>{9e671547-6550-414c-8170-a013093aafe7}</UniqueIdentifier>
</Filter>
<Filter Include="7z\Compress">
<UniqueIdentifier>{9a0c91a6-c1ce-4a79-94d6-2459b4171bff}</UniqueIdentifier>
</Filter>
<Filter Include="fex">
<UniqueIdentifier>{e99e7ce7-b7cb-42d2-8e89-e2005d013c0e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="7z_C\7zCrc.c">
<Filter>7z</Filter>
</ClCompile>
<ClCompile Include="7z_C\Alloc.c">
<Filter>7z</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zAlloc.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zBuffer.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zDecode.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zExtract.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zHeader.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zIn.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zItem.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Archive\7z\7zMethodID.c">
<Filter>7z\Archive</Filter>
</ClCompile>
<ClCompile Include="7z_C\Compress\Branch\BranchX86.c">
<Filter>7z\Compress</Filter>
</ClCompile>
<ClCompile Include="7z_C\Compress\Branch\BranchX86_2.c">
<Filter>7z\Compress</Filter>
</ClCompile>
<ClCompile Include="7z_C\Compress\Lzma\LzmaDecode.c">
<Filter>7z\Compress</Filter>
</ClCompile>
<ClCompile Include="fex\abstract_file.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Data_Reader.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\fex.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\File_Extractor.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Gzip_Reader.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Single_File_Extractor.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\unzip.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Zip7_Extractor.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Zip_Extractor.cpp">
<Filter>fex</Filter>
</ClCompile>
<ClCompile Include="fex\Zlib_Inflater.cpp">
<Filter>fex</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="7z_C\7zCrc.h">
<Filter>7z</Filter>
</ClInclude>
<ClInclude Include="7z_C\Alloc.h">
<Filter>7z</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zAlloc.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zBuffer.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zDecode.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zExtract.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zHeader.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zIn.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zItem.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Archive\7z\7zMethodID.h">
<Filter>7z\Archive</Filter>
</ClInclude>
<ClInclude Include="7z_C\Compress\Branch\BranchTypes.h">
<Filter>7z\Compress</Filter>
</ClInclude>
<ClInclude Include="7z_C\Compress\Branch\BranchX86.h">
<Filter>7z\Compress</Filter>
</ClInclude>
<ClInclude Include="7z_C\Compress\Branch\BranchX86_2.h">
<Filter>7z\Compress</Filter>
</ClInclude>
<ClInclude Include="7z_C\Compress\Lzma\LzmaDecode.h">
<Filter>7z\Compress</Filter>
</ClInclude>
<ClInclude Include="7z_C\Compress\Lzma\LzmaTypes.h">
<Filter>7z\Compress</Filter>
</ClInclude>
<ClInclude Include="7z_C\Types.h">
<Filter>7z</Filter>
</ClInclude>
<ClInclude Include="fex\abstract_file.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\blargg_common.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\blargg_config.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\blargg_endian.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\blargg_source.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Data_Reader.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\fex.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\File_Extractor.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Gzip_Reader.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Single_File_Extractor.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\unzip.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Zip7_Extractor.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Zip_Extractor.h">
<Filter>fex</Filter>
</ClInclude>
<ClInclude Include="fex\Zlib_Inflater.h">
<Filter>fex</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="7z_C\7zC.txt">
<Filter>7z</Filter>
</None>
<None Include="7z_C\changes.txt">
<Filter>7z</Filter>
</None>
<None Include="7z_C\lzma.txt">
<Filter>7z</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -1,53 +0,0 @@
/* C example that opens an archive, lists its contents, and
extracts the first several characters of each file. */
#include "fex/fex.h"
#include <stdlib.h>
#include <stdio.h>
/* If error is not NULL, prints it and exits program */
static void error( const char* error );
int main( int argc, char* argv [] )
{
/* Path to archive */
const char* path = (argc > 1 ? argv [argc - 1] : "test.zip");
/* Open archive */
fex_err_t err;
File_Extractor* fex = fex_open( path, &err );
error( err );
/* Iterate over each file in archive */
while ( !fex_done( fex ) )
{
char buf [50] = "";
/* Print size and name */
const char* name = fex_name( fex );
long size = fex_size( fex );
printf( "## %3ld K %s\n", size / 1024, name );
/* Print first several characters of data */
error( fex_read( fex, buf, (size < 49 ? size : 49) ) );
printf( "%s\n", buf );
/* Go to next file in archive */
error( fex_next( fex ) );
}
/* Cleanup */
fex_close( fex );
return 0;
}
void error( const char* error )
{
if ( error )
{
fprintf( stderr, "Error: %s\n", error );
exit( EXIT_FAILURE );
}
}

View File

@ -1,209 +0,0 @@
File_Extractor 0.4.3
--------------------
Author : Shay Green <gblargg@gmail.com>
Website : http://www.slack.net/~ant/
License : GNU Lesser General Public License (LGPL) for all except unrar
Language: C or C++
Contents
--------
* Overview
* Limitations
* C and C++ interfaces
* Extracting file data
* Alternate interfaces: unzip.h and unrarlib.h
* Minimal version: fex_mini.cpp
* Library compilation
* Error handling
* Solving problems
* Thanks
Overview
--------
This library contains several modules that support different archive
formats. They have a common interface allowing an archive to be opened,
scanned, and extracted from. To use an archive, do the following:
* Open file using appropriate extractor.
* See if at end of archive.
* Get info for current file and/or extract data from it.
* Go to next file and check if at end of archive and repeat above.
* If desired at any point, rewind and scan the archive again.
* When done, close archive.
If support for one or more archive types is not needed, many of the
library sources can be eliminated. Refer to the files list in readme.txt
to find what can be removed.
Details
-------
All archives:
* A file's checksum is verified only if all the file's data is read from
the archive.
* Encryption, segmentation, 2GB and larger files, and other extra
features are not supported.
GZ archives:
* Only gzip archives of a single file are supported. If it has multiple
files, the reported size will be wrong. Multi-file gzip files are rare.
ZIP archives:
* Supports files compressed using deflation or no compression. Other
compression schemes are not supported.
* Archive must have a valid directory structure at the end.
* Optimized file access reduces reads and keeps them aligned
RAR archives:
* Support for really old 1.x archives might not work. Send me some test
archives as I couldn't find any.
7-zip:
* Solid archives currently can use lots of memory.
* Modification date isn't supported.
C and C++ interfaces
--------------------
This library includes a C interface in fex.h, which can be used from C
and C++. If this is being compiled as a shared library (rather than
linking statically), only the C interface in fex.h should be used since
it will change less in future versions.
The native C++ interface is in File_Extractor.h and supports more ways
of reading data and accessing files. Both interfaces can be used
together in C++ code without problems. The interfaces correspond in a
consistent way:
C interface C++ interface
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
File_Extractor* fex; File_Extractor* fex;
fex_open( path, &fex ); fex_open( path, &fex );
fex_done( fex ); fex->done();
fex_read( fex, out, count ); fex->read( out, count );
fex_close( fex ); delete fex;
The archive extractor classes are derived from File_Extractor, which
allows a File_Extractor* to point to any type of extractor. There is no
need to use concrete types directly (Zip_Extractor, etc.).
Extracting file data
--------------------
Data for a file in an archive can be accessed in three ways:
* Make one or more calls to read().
* Get a pointer to the file's data in memory.
* Have extractor write data to Data_Writer you provide (C++ only).
Each archive type has an optimal access method that you might use if you
were using only one archive type and wanted to avoid extra memory
allocation or copying. Single_File_Extractor and Zip_Extractor favor
read(), Zip7_Extractor favors getting a pointer to data in memory, and
Rar_Extractor favors writing the data to a Data_Writer.
You should generally use whatever method is most convenient in your
program. In most cases you will be keeping a copy of the data in memory
after closing the archive, so you'll want to use read(). As long as you
read the ENTIRE file's contents in one call to read(), your code will be
most efficient and won't involve any extra memory allocation. If you
only need the first portion of the file and will not be reading the rest
(for example, if scanning headers only), you can use the optimized
read_once() function instead of the normal read().
Alternate interfaces: unzip.h and unrarlib.h
--------------------------------------------
If your code already uses the unzip.h or unrarlib.h library, you can
begin using fex with minimal/no changes to your code by using the
included wrappers. Most unrarlib.h functions are supported, and the main
unzip.h functions are supported. Only basic file information is returned
by each; things like dates and directories are not supported. These
header files should NOT be used if you're writing new code, since they
are inferior to the fex.h interface.
Both of these header files define FEX_WRAPPER to 1, so your code can
check for that macro and if defined, support additional archive formats
rather than just .rar or .zip.
Minimal version: fex_mini.cpp
-----------------------------
You can use fex_mini.cpp and fex.h as an absolute minimum version. If
you have zlib installed and HAVE_ZLIB_H defined, gzipped files are
supported, otherwise only uncompressed files are supported. No other
source files are required for this version. No changes to your source
are necessary as long as you use only fex.h functionality.
Library compilation
-------------------
While this library is written in C++, it should easily link in a C
program WITHOUT needing the standard C++ library. It doesn't use
exception handling or run-time type information (RTTI), so you can
disable these in your C++ compiler to increase efficiency.
If you're building a shared library (DLL), I HIGHLY recommend only
exporting the C interface from fex.h, as the C++ interface exposes
implementation details that will surely break link compatibility across
versions. If you aren't familiar with symbol exporting, just be sure you
only use fex.h to access the shared library.
If you're using C and compiling with GCC, I recommend the following
command-line options when compiling the library source, otherwise GCC
will insert calls to the standard C++ library and require that it be
linked in:
-fno-rtti -fno-exceptions
Error handling
--------------
Functions that can fail have a return type of fex_err_t (blargg_err_t in
the C++ interfaces), which is a pointer to an error string, const char*.
If a function is successful it returns NULL. Logic errors that can be
easily avoided are checked with debug-only assertions; error return
values are only used for genuine run-time errors that can't be easily
prevented in advance (out of memory, I/O errors, incompatible file
data). All return values should be checked after calling library
functions.
To improve usability for C programmers, C++ programmers unfamiliar with
exceptions, and compatibility with older C++ compilers, the library does
NOT throw any C++ exceptions, and uses malloc() instead of the standard
operator new. This means that in C++ you MUST check for NULL when
creating a library object with the new operator.
Solving problems
----------------
If you're having problems, try the following:
* Enable debugging support in your environment. This enables assertions
and other run-time checks. In particular, be sure NDEBUG isn't defined.
* Turn the compiler's optimizer is off. Sometimes an optimizer generates
bad code.
* If multiple threads are being used, ensure that only one at a time is
accessing a given set of objects from the library. This library is not
in general thread-safe, though independent objects can be used in
separate threads.
* If all else fails, see if the demo works.
Thanks
------
Thanks to Richard Bannister, Kode54, and DJRobX for testing and giving
feedback for the library. Thanks to the authors of zlib, unrar, and
7-zip.
--
Shay Green <gblargg@gmail.com>

View File

@ -1,323 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Data_Reader.h"
#include "blargg_endian.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
const char Data_Reader::eof_error [] = "Unexpected end of file";
blargg_err_t Data_Reader::read( void* p, long s )
{
long result = read_avail( p, s );
if ( result == s )
return 0;
if ( result < 0 )
return "Read error";
return eof_error;
}
blargg_err_t Data_Reader::skip( long count )
{
char buf [512];
while ( count )
{
long n = sizeof buf;
if ( n > count )
n = count;
count -= n;
RETURN_ERR( read( buf, n ) );
}
return 0;
}
long File_Reader::remain() const { return size() - tell(); }
blargg_err_t File_Reader::skip( long n )
{
assert( n >= 0 );
if ( !n )
return 0;
return seek( tell() + n );
}
// Subset_Reader
Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
{
in = dr;
remain_ = dr->remain();
if ( remain_ > size )
remain_ = size;
}
long Subset_Reader::remain() const { return remain_; }
long Subset_Reader::read_avail( void* p, long s )
{
if ( s > remain_ )
s = remain_;
remain_ -= s;
return in->read_avail( p, s );
}
// Remaining_Reader
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
{
header = (char const*) h;
header_end = header + size;
in = r;
}
long Remaining_Reader::remain() const { return header_end - header + in->remain(); }
long Remaining_Reader::read_first( void* out, long count )
{
long first = header_end - header;
if ( first )
{
if ( first > count )
first = count;
void const* old = header;
header += first;
memcpy( out, old, first );
}
return first;
}
long Remaining_Reader::read_avail( void* out, long count )
{
long first = read_first( out, count );
long second = count - first;
if ( second )
{
second = in->read_avail( (char*) out + first, second );
if ( second <= 0 )
return second;
}
return first + second;
}
blargg_err_t Remaining_Reader::read( void* out, long count )
{
long first = read_first( out, count );
long second = count - first;
if ( !second )
return 0;
return in->read( (char*) out + first, second );
}
// Mem_File_Reader
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
begin( (const char*) p ),
size_( s )
{
pos = 0;
}
long Mem_File_Reader::size() const { return size_; }
long Mem_File_Reader::read_avail( void* p, long s )
{
long r = remain();
if ( s > r )
s = r;
memcpy( p, begin + pos, s );
pos += s;
return s;
}
long Mem_File_Reader::tell() const { return pos; }
blargg_err_t Mem_File_Reader::seek( long n )
{
if ( n > size_ )
return eof_error;
pos = n;
return 0;
}
// Callback_Reader
Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
callback( c ),
data( d )
{
remain_ = size;
}
long Callback_Reader::remain() const { return remain_; }
long Callback_Reader::read_avail( void* out, long count )
{
if ( count > remain_ )
count = remain_;
if ( Callback_Reader::read( out, count ) )
return -1;
return 0;
}
blargg_err_t Callback_Reader::read( void* out, long count )
{
if ( count > remain_ )
return eof_error;
return callback( data, out, count );
}
// Std_File_Reader
Std_File_Reader::Std_File_Reader() : file_( 0 ) { }
Std_File_Reader::~Std_File_Reader() { close(); }
blargg_err_t Std_File_Reader::open( const char* path )
{
file_ = fopen( path, "rb" );
if ( !file_ )
return "Couldn't open file";
return 0;
}
void Std_File_Reader::make_unbuffered()
{
if ( setvbuf( (FILE*) file_, 0, _IONBF, 0 ) )
check( false ); // shouldn't fail, but OK if it does
}
long Std_File_Reader::size() const
{
long pos = tell();
fseek( (FILE*) file_, 0, SEEK_END );
long result = tell();
fseek( (FILE*) file_, pos, SEEK_SET );
return result;
}
long Std_File_Reader::read_avail( void* p, long s )
{
return fread( p, 1, s, (FILE*) file_ );
}
blargg_err_t Std_File_Reader::read( void* p, long s )
{
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
return 0;
if ( feof( (FILE*) file_ ) )
return eof_error;
return "Couldn't read from file";
}
long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); }
blargg_err_t Std_File_Reader::seek( long n )
{
if ( !fseek( (FILE*) file_, n, SEEK_SET ) )
return 0;
if ( n > size() )
return eof_error;
return "Error seeking in file";
}
void Std_File_Reader::close()
{
if ( file_ )
{
fclose( (FILE*) file_ );
file_ = 0;
}
}
// Gzip_File_Reader
#ifdef HAVE_ZLIB_H
#include "zlib.h"
static const char* get_gzip_eof( const char* path, long* eof )
{
FILE* file = fopen( path, "rb" );
if ( !file )
return "Couldn't open file";
unsigned char buf [4];
if ( fread( buf, 2, 1, file ) > 0 && buf [0] == 0x1F && buf [1] == 0x8B )
{
fseek( file, -4, SEEK_END );
fread( buf, 4, 1, file );
*eof = get_le32( buf );
}
else
{
fseek( file, 0, SEEK_END );
*eof = ftell( file );
}
const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0;
fclose( file );
return err;
}
Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { }
Gzip_File_Reader::~Gzip_File_Reader() { close(); }
blargg_err_t Gzip_File_Reader::open( const char* path )
{
close();
RETURN_ERR( get_gzip_eof( path, &size_ ) );
file_ = gzopen( path, "rb" );
if ( !file_ )
return "Couldn't open file";
return 0;
}
long Gzip_File_Reader::size() const { return size_; }
long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); }
long Gzip_File_Reader::tell() const { return gztell( file_ ); }
blargg_err_t Gzip_File_Reader::seek( long n )
{
if ( gzseek( file_, n, SEEK_SET ) >= 0 )
return 0;
if ( n > size_ )
return eof_error;
return "Error seeking in file";
}
void Gzip_File_Reader::close()
{
if ( file_ )
{
gzclose( file_ );
file_ = 0;
}
}
#endif

View File

@ -1,161 +0,0 @@
// Lightweight interface for reading data
// File_Extractor 0.4.3
#ifndef DATA_READER_H
#define DATA_READER_H
#include "blargg_common.h"
// Supports reading and finding out how many bytes are remaining
class Data_Reader {
public:
virtual ~Data_Reader() { }
static const char eof_error []; // returned by read() when request goes beyond end
// Reads at most n bytes and returns number actually read, or negative if error.
// Trying to read past end of file is NOT considered an error.
virtual long read_avail( void*, long n ) BLARGG_PURE( { (void) n; return 0; } )
// Read exactly n bytes and returns error if they couldn't ALL be read.
// Reading past end of file results in eof_error.
virtual blargg_err_t read( void*, long n );
// Number of bytes remaining until end of file
virtual long remain() const BLARGG_PURE( { return 0; } )
// Reads and discards n bytes. Skipping past end of file results in eof_error.
virtual blargg_err_t skip( long n );
public:
Data_Reader() { }
typedef blargg_err_t error_t; // deprecated
BLARGG_DISABLE_NOTHROW
private:
// noncopyable
Data_Reader( const Data_Reader& );
Data_Reader& operator = ( const Data_Reader& );
};
// Supports seeking in addition to Data_Reader operations
class File_Reader : public Data_Reader {
public:
// Size of file
virtual long size() const BLARGG_PURE( { return 0; } )
// Current position in file
virtual long tell() const BLARGG_PURE( { return 0; } )
// Goes to new position
virtual blargg_err_t seek( long ) BLARGG_PURE( { return 0; } )
long remain() const;
blargg_err_t skip( long n );
};
// Disk file reader
class Std_File_Reader : public File_Reader {
public:
blargg_err_t open( const char* path );
void close();
// Switches to unbuffered mode. Useful if you are doing your
// own buffering already.
void make_unbuffered();
public:
Std_File_Reader();
~Std_File_Reader();
long size() const;
blargg_err_t read( void*, long );
long read_avail( void*, long );
long tell() const;
blargg_err_t seek( long );
private:
void* file_;
};
// Treats range of memory as a file
class Mem_File_Reader : public File_Reader {
public:
Mem_File_Reader( const void* begin, long size );
public:
long size() const;
long read_avail( void*, long );
long tell() const;
blargg_err_t seek( long );
private:
const char* const begin;
const long size_;
long pos;
};
// Makes it look like there are only count bytes remaining
class Subset_Reader : public Data_Reader {
public:
Subset_Reader( Data_Reader*, long count );
public:
long remain() const;
long read_avail( void*, long );
private:
Data_Reader* in;
long remain_;
};
// Joins already-read header and remaining data into original file.
// Meant for cases where you've already read header and don't want
// to seek and re-read data (for efficiency).
class Remaining_Reader : public Data_Reader {
public:
Remaining_Reader( void const* header, long header_size, Data_Reader* );
public:
long remain() const;
long read_avail( void*, long );
blargg_err_t read( void*, long );
private:
char const* header;
char const* header_end;
Data_Reader* in;
long read_first( void* out, long count );
};
// Invokes callback function to read data. Size of data must be specified in advance.
// Passes user_data unchanged to your callback.
class Callback_Reader : public Data_Reader {
public:
typedef const char* (*callback_t)( void* user_data, void* out, long count );
Callback_Reader( callback_t, long size, void* user_data = 0 );
public:
long read_avail( void*, long );
blargg_err_t read( void*, long );
long remain() const;
private:
callback_t const callback;
void* const data;
long remain_;
};
#ifdef HAVE_ZLIB_H
// Gzip compressed file reader
class Gzip_File_Reader : public File_Reader {
public:
blargg_err_t open( const char* path );
void close();
public:
Gzip_File_Reader();
~Gzip_File_Reader();
long size() const;
long read_avail( void*, long );
long tell() const;
blargg_err_t seek( long );
private:
void* file_;
long size_;
};
#endif
#endif

View File

@ -1,247 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "File_Extractor.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
const char fex_wrong_file_type [] = "Archive format not supported";
File_Extractor::File_Extractor( fex_type_t t ) :
type_( t )
{
user_data_ = 0;
user_cleanup_ = 0;
init_state();
}
// Open
void File_Extractor::open_filter_( const char*, Std_File_Reader* ) { }
blargg_err_t File_Extractor::open( const char* path )
{
Std_File_Reader* in = BLARGG_NEW Std_File_Reader;
CHECK_ALLOC( in );
blargg_err_t err = in->open( path );
if ( !err )
{
open_filter_( path, in );
err = this->open( in );
}
if ( err )
{
delete in;
return err;
}
own_file();
return 0;
}
blargg_err_t File_Extractor::open( File_Reader* input )
{
require( input->tell() == 0 ); // needs to be at beginning
close();
reader_ = input;
blargg_err_t err = open_();
if ( !err )
done_ = false;
else
close();
return err;
}
// Close
void File_Extractor::init_state()
{
done_ = true;
scan_only_ = false;
reader_ = 0;
own_file_ = false;
own_data_ = 0;
clear_file();
}
void File_Extractor::close()
{
close_();
if ( own_file_ && reader_ )
delete reader_;
clear_file();
init_state();
}
File_Extractor::~File_Extractor()
{
// fails if derived class didn't call close() in its destructor
check( !own_file_ && !reader_ );
if ( user_cleanup_ )
user_cleanup_( user_data_ );
}
// Scanning
void File_Extractor::free_data()
{
data_ptr_ = 0;
free( own_data_ );
own_data_ = 0;
}
void File_Extractor::clear_file()
{
set_info( 0, 0 );
data_pos_ = 0;
free_data();
clear_file_();
}
void File_Extractor::set_info( long size, const char* name, unsigned long date )
{
size_ = size;
name_ = name;
date_ = (date != 0xFFFFFFFF ? date : 0);
}
blargg_err_t File_Extractor::next()
{
if ( done() )
return "End of archive";
clear_file();
blargg_err_t err = next_();
if ( err )
done_ = true;
if ( done_ )
clear_file();
return err;
}
blargg_err_t File_Extractor::rewind()
{
if ( !reader_ )
return "No open archive";
done_ = false;
scan_only_ = false;
clear_file();
blargg_err_t err = rewind_();
if ( err )
{
done_ = true;
clear_file();
}
return err;
}
// Full extraction
blargg_err_t File_Extractor::data_( byte const*& out )
{
if ( !own_data_ )
CHECK_ALLOC( own_data_ = (byte*) malloc( size_ ? size_ : 1 ) );
out = own_data_;
return read_once( own_data_, size_ );
}
unsigned char const* File_Extractor::data( blargg_err_t* error_out )
{
const char* error = 0;
if ( !reader_ )
{
error = eof_error;
}
else if ( !data_ptr_ )
{
error = data_( data_ptr_ );
if ( error )
free_data();
}
if ( error_out )
*error_out = error;
return data_ptr_;
}
blargg_err_t File_Extractor::extract( Data_Writer& out )
{
blargg_err_t error;
byte const* p = data( &error );
RETURN_ERR( error );
return out.write( p, size_ );
}
blargg_err_t File_Extractor::read_once( void* out, long count )
{
Mem_Writer mem( out, count, 1 );
return extract( mem );
}
// Data_Reader functions
long File_Extractor::remain() const { return size_ - data_pos_; }
long File_Extractor::read_avail( void* out, long count )
{
if ( count )
{
long r = remain();
if ( count > r )
count = r;
if ( read( out, count ) )
count = -1;
}
return count;
}
blargg_err_t File_Extractor::read( void* out, long count )
{
if ( count > remain() )
return "End of file";
if ( count == size_ && !data_ptr_ )
{
// avoid temporary buffer when reading entire file in one call
assert( data_pos_ == 0 );
RETURN_ERR( read_once( out, count ) );
}
else
{
if ( count && !data_ptr_ )
{
blargg_err_t err;
data( &err ); // sets data_ptr_
RETURN_ERR( err );
}
memcpy( out, data_ptr_ + data_pos_, count );
}
data_pos_ += count;
if ( data_pos_ == size_ )
free_data();
return 0;
}

View File

@ -1,153 +0,0 @@
// Compressed file archive interface (C++)
// File_Extractor 0.4.3
#ifndef FILE_EXTRACTOR_H
#define FILE_EXTRACTOR_H
#include "fex.h"
#include "blargg_common.h"
#include "abstract_file.h"
struct File_Extractor : private Data_Reader {
public:
// Open/close
// Opens archive
blargg_err_t open( const char* path );
// Opens archive from custom data source. Keeps pointer to input
// until close(), but does not delete reader at close() unless you
// call own_file() before then.
blargg_err_t open( File_Reader* input );
// Transfers ownership of current input file passed to open() so that
// it will be deleted on close()
void own_file() { own_file_ = true; }
// Closes archive and frees memory
void close();
// Scanning
// True if end of archive has been reached
bool done() const { return done_; }
// Path of current file in archive, using '/' as directory separator
const char* name() const { return name_; }
// Size of current file, in bytes
long size() const { return size_; }
// Modification date of file, in MS-DOS format (0 if unavailable).
unsigned long dos_date() const { return date_; }
// Goes to next file (skips directories)
blargg_err_t next();
// Goes back to first file in archive
blargg_err_t rewind();
// Data extraction
// Read exactly n bytes and returns error if they couldn't ALL be read.
// Reading past end of file results in eof_error.
blargg_err_t read( void* out, long n );
// Reads at most n bytes and returns number actually read, or negative if error.
// Trying to read past end of file is NOT considered an error.
long read_avail( void* out, long n );
// Number of bytes remaining until end of current file
long remain() const;
// Reads and discards n bytes. Skipping past end of file results in eof_error.
blargg_err_t skip( long n ) { return Data_Reader::skip( n ); }
// Data_Reader to current file's data, so you can use standard Data_Reader
// interface and not have to treat archives specially.
Data_Reader& reader() { return *this; }
// Alternate ways of extracting file. Only one method may be used
// once before calling next() or rewind().
// Extracts first n bytes and ignores rest. Faster than a normal read since it
// doesn't have to be prepared to read/decompress more data.
virtual blargg_err_t read_once( void* out, long n );
// Extracts all data and writes it to out
virtual blargg_err_t extract( Data_Writer& out );
// Gets pointer to file's data. Returned pointer is valid until next call to
// next(), rewind(), close(), or open(). Sets *error_out to error. OK to call
// more than once in a row; returns same pointer in that case.
typedef unsigned char byte;
byte const* data( blargg_err_t* error_out );
// Other features
// Type of this extractor (fex_zip_type, etc.)
fex_type_t type() const { return type_; }
// Hints that archive will either be only scanned (true), or might be extracted
// from (false), improving performance on solid archives. Calling rewind()
// resets this to the best default.
void scan_only( bool b = true ) { scan_only_ = b; }
// Sets/gets pointer to data you want to associate with this object.
// You can use this for whatever you want.
void set_user_data( void* p ) { user_data_ = p; }
void* user_data() const { return user_data_; }
// Registers cleanup function to be called when deleting this object. Passes
// user_data to cleanup function. Pass NULL to clear any cleanup function.
void set_user_cleanup( fex_user_cleanup_t func ) { user_cleanup_ = func; }
virtual ~File_Extractor();
public:
BLARGG_DISABLE_NOTHROW
File_Extractor( fex_type_t );
Data_Reader::eof_error;
protected:
// Services for extractors
File_Reader& file() const { return *reader_; }
void set_done() { done_ = true; }
void set_info( long size, const char* name, unsigned long date = 0 );
bool is_scan_only() const { return scan_only_; }
// Overridden by extractors
virtual void open_filter_( const char* path, Std_File_Reader* );
virtual blargg_err_t open_() BLARGG_PURE( { return 0; } )
virtual blargg_err_t next_() BLARGG_PURE( { return 0; } )
virtual blargg_err_t rewind_() BLARGG_PURE( { return 0; } )
virtual void close_() BLARGG_PURE( { } )
virtual void clear_file_() { }
virtual blargg_err_t data_( byte const*& out );
private:
fex_type_t const type_;
File_Reader* reader_;
bool own_file_;
bool scan_only_;
bool done_;
const char* name_;
unsigned long date_;
long size_;
long data_pos_; // current position in data
byte const* data_ptr_;
byte* own_data_; // memory we allocated for data
void* user_data_;
fex_user_cleanup_t user_cleanup_;
void init_state();
void clear_file();
void free_data();
};
// Default to Std_File_Reader for archive access
#ifndef FEX_FILE_READER
#define FEX_FILE_READER Std_File_Reader
#endif
#endif

View File

@ -1,109 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Gzip_Reader.h"
#include "blargg_endian.h"
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
void Gzip_Reader::close()
{
in = 0;
tell_ = 0;
size_ = 0;
inflater.end();
}
Gzip_Reader::Gzip_Reader() { close(); }
Gzip_Reader::~Gzip_Reader() { }
static blargg_err_t gzip_reader_read( void* file, void* out, long* count )
{
*count = ((File_Reader*) file)->read_avail( out, *count );
return (*count < 0 ? "Read error" : 0);
}
blargg_err_t Gzip_Reader::open( File_Reader* new_in )
{
close();
RETURN_ERR( inflater.begin( gzip_reader_read, new_in ) );
RETURN_ERR( inflater.set_mode( inflater.mode_auto ) );
size_ = -1; // defer seeking to end of file until size is actually needed
in = new_in;
return 0;
}
blargg_err_t Gzip_Reader::calc_size()
{
long size = in->size();
if ( inflater.deflated() )
{
byte trailer [4];
long pos = in->tell();
RETURN_ERR( in->seek( size - sizeof trailer ) );
RETURN_ERR( in->read( trailer, sizeof trailer ) );
RETURN_ERR( in->seek( pos ) );
size = get_le32( trailer );
}
size_ = size;
return 0;
}
long Gzip_Reader::remain() const
{
if ( size_ < 0 )
{
if ( !in )
return 0;
// need to cast away constness to change cached value
if ( ((Gzip_Reader*) this)->calc_size() )
return -1;
}
return size_ - tell_;
}
blargg_err_t Gzip_Reader::read_( void* out, long* count )
{
blargg_err_t err = inflater.read( out, count );
tell_ += *count;
if ( size_ >= 0 && tell_ > size_ )
{
tell_ = size_;
return inflater.corrupt_error;
}
return err;
}
blargg_err_t Gzip_Reader::read( void* out, long count )
{
if ( in )
{
long actual = count;
RETURN_ERR( read_( out, &actual ) );
if ( actual == count )
return 0;
}
return eof_error;
}
long Gzip_Reader::read_avail( void* out, long count )
{
if ( !in || read_( out, &count ) )
count = -1;
return count;
}

View File

@ -1,35 +0,0 @@
// Transparently decompresses gzip files, as well as uncompressed
// File_Extractor 0.4.3
#ifndef GZIP_READER_H
#define GZIP_READER_H
#include "Data_Reader.h"
#include "Zlib_Inflater.h"
class Gzip_Reader : public Data_Reader {
public:
error_t open( File_Reader* );
void close();
long tell() const { return tell_; }
// True if file is compressed
bool deflated() const { return inflater.deflated(); }
public:
Gzip_Reader();
~Gzip_Reader();
long remain() const;
error_t read( void*, long );
long read_avail( void*, long );
private:
File_Reader* in;
long tell_;
long size_;
Zlib_Inflater inflater;
error_t calc_size();
blargg_err_t read_( void* out, long* count );
};
#endif

View File

@ -1,88 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Single_File_Extractor.h"
#include <string.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
Single_File_Extractor::Single_File_Extractor() : File_Extractor( fex_bin_type )
{
size_ = 0;
}
extern "C" {
static File_Extractor* new_single_file() { return BLARGG_NEW Single_File_Extractor; }
}
fex_type_t_ const fex_gz_type [1] = {{ "GZ", &new_single_file }};
fex_type_t_ const fex_bin_type [1] = {{ "" , &new_single_file }};
Single_File_Extractor::~Single_File_Extractor() { close(); }
void Single_File_Extractor::close_() { gr.close(); }
void Single_File_Extractor::set_name( const char* n )
{
name [sizeof name-1] = 0;
strncpy( name, n, sizeof name-1 );
}
void Single_File_Extractor::open_filter_( const char* path, Std_File_Reader* file )
{
file->make_unbuffered(); // faster since Gzip_Reader already buffers data
const char* name = strrchr( path, '\\' ); // DOS
if ( !name )
name = strrchr( path, '/' ); // UNIX
if ( !name )
name = strrchr( path, ':' ); // Mac
if ( !name )
name = path;
set_name( name );
}
blargg_err_t Single_File_Extractor::open_()
{
RETURN_ERR( gr.open( &file() ) );
size_ = gr.remain();
if ( size_ < 0 )
return "Read error";
set_info( size_, name );
return 0;
}
blargg_err_t Single_File_Extractor::rewind_()
{
if ( gr.tell() )
{
RETURN_ERR( file().seek( 0 ) );
RETURN_ERR( gr.open( &file() ) );
}
set_info( size_, name );
return 0;
}
blargg_err_t Single_File_Extractor::next_()
{
set_done();
return 0;
}
long Single_File_Extractor::remain () const { return size_ - gr.tell(); }
long Single_File_Extractor::read_avail( void* p, long n ) { return gr.read_avail( p, n ); }
blargg_err_t Single_File_Extractor::read ( void* p, long n ) { return gr.read( p, n ); }
blargg_err_t Single_File_Extractor::read_once ( void* p, long n ) { return read( p, n ); }

View File

@ -1,36 +0,0 @@
// Presents a single file as an "archive" of just that file.
// Also handles gzipped file.
// File_Extractor 0.4.3
#ifndef SINGLE_FILE_EXTRACTOR_H
#define SINGLE_FILE_EXTRACTOR_H
#include "File_Extractor.h"
#include "Gzip_Reader.h"
class Single_File_Extractor : public File_Extractor {
public:
// Set reported name of file
void set_name( const char* );
public:
Single_File_Extractor();
~Single_File_Extractor();
File_Extractor::open;
long read_avail( void*, long );
blargg_err_t read( void*, long );
long remain() const;
blargg_err_t read_once( void*, long );
protected:
void open_filter_( const char*, Std_File_Reader* );
blargg_err_t open_();
blargg_err_t next_();
blargg_err_t rewind_();
void close_();
private:
Gzip_Reader gr;
long size_;
char name [1024];
};
#endif

View File

@ -1,180 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Zip7_Extractor.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
extern "C" {
#include "../7z_C/Archive/7z/7zExtract.h"
#include "../7z_C/7zCrc.h"
}
/* Copyright (C) 2005-2008 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
static ISzAlloc alloc = { SzAlloc, SzFree };
static ISzAlloc alloc_temp = { SzAllocTemp, SzFreeTemp };
struct Zip7_Extractor_Impl
{
ISzInStream stream; // must be first
CArchiveDatabaseEx db;
// SzExtract state
UInt32 block_index;
Byte* buf;
size_t buf_size;
File_Reader* in;
#ifdef _LZMA_IN_CB
enum { read_buf_size = 32 * 1024L };
char read_buf [read_buf_size];
#endif
};
extern "C"
{
#ifdef _LZMA_IN_CB
static SZ_RESULT zip7_read_( void* data, void** out, size_t size, size_t* size_out )
{
assert( out && size_out );
Zip7_Extractor_Impl* impl = (Zip7_Extractor_Impl*) data;
if ( size > impl->read_buf_size )
size = impl->read_buf_size;
*out = impl->read_buf;
*size_out = impl->in->read_avail( impl->read_buf, size );
return SZ_OK;
}
#else
static SZ_RESULT zip7_read_( void* data, void* out, size_t size, size_t* size_out )
{
assert( out && size_out );
Zip7_Extractor_Impl* impl = (Zip7_Extractor_Impl*) data;
*size_out = impl->in->read_avail( out, size );
return SZ_OK;
}
#endif
static SZ_RESULT zip7_seek_( void* data, CFileSize offset )
{
Zip7_Extractor_Impl* impl = (Zip7_Extractor_Impl*) data;
if ( impl->in->seek( offset ) )
return SZE_FAIL;
return SZ_OK;
}
}
Zip7_Extractor::Zip7_Extractor() : File_Extractor( fex_7z_type )
{
impl = 0;
}
extern "C" {
static File_Extractor* new_7z() { return BLARGG_NEW Zip7_Extractor; }
}
fex_type_t_ const fex_7z_type [1] = {{ "7Z", &new_7z }};
Zip7_Extractor::~Zip7_Extractor() { close(); }
static const char* zip7_err( int err )
{
switch ( err )
{
case SZ_OK: return 0;
case SZE_OUTOFMEMORY: return "Out of memory";
case SZE_CRC_ERROR: return "Corrupt 7-zip file";
case SZE_NOTIMPL: return "Unsupported 7-zip feature";
//case SZE_FAIL:
//case SZE_DATA_ERROR:
//case SZE_ARCHIVE_ERROR:
}
return "7-zip error";
}
blargg_err_t Zip7_Extractor::open_()
{
if ( !impl )
CHECK_ALLOC( impl = (Zip7_Extractor_Impl*) malloc( sizeof *impl ) );
impl->stream.Read = zip7_read_;
impl->stream.Seek = zip7_seek_;
impl->in = &file();
impl->block_index = (unsigned) -1;
impl->buf = 0;
impl->buf_size = 0;
CrcGenerateTable();
SzArDbExInit( &impl->db );
int code = SzArchiveOpen( &impl->stream, &impl->db, &alloc, &alloc_temp );
RETURN_ERR( (code == SZE_ARCHIVE_ERROR ? fex_wrong_file_type : zip7_err( code )) );
return rewind();
}
blargg_err_t Zip7_Extractor::rewind_()
{
index = -1;
return next();
}
void Zip7_Extractor::close_()
{
if ( impl )
{
if ( impl->in )
{
impl->in = 0;
SzArDbExFree( &impl->db, alloc.Free );
}
alloc.Free( impl->buf );
free( impl );
impl = 0;
}
}
blargg_err_t Zip7_Extractor::next_()
{
while ( ++index < (int) impl->db.Database.NumFiles )
{
CFileItem const& item = impl->db.Database.Files [index];
if ( !item.IsDirectory )
{
// TODO: support date
// stored as 64-bit value, divide by 10000000 (ten million) to get seconds
//item.LastWriteTime.Low + (.High << 32)
set_info( item.Size, item.Name );
return 0;
}
}
set_done();
return 0;
}
blargg_err_t Zip7_Extractor::data_( byte const*& out )
{
if ( !impl )
return "Archive not open";
size_t offset = 0;
size_t size = 0;
RETURN_ERR( zip7_err( SzExtract( &impl->stream, &impl->db, index,
&impl->block_index, &impl->buf, &impl->buf_size,
&offset, &size, &alloc, &alloc_temp ) ) );
assert( size == (size_t) this->size() );
out = impl->buf + offset;
return 0;
}

View File

@ -1,28 +0,0 @@
// 7-zip archive extractor
// File_Extractor 0.4.3
#ifndef ZIP7_EXTRACTOR_H
#define ZIP7_EXTRACTOR_H
#include "File_Extractor.h"
struct Zip7_Extractor_Impl;
class Zip7_Extractor : public File_Extractor {
public:
Zip7_Extractor();
~Zip7_Extractor();
protected:
blargg_err_t open_();
blargg_err_t next_();
blargg_err_t rewind_();
void close_();
blargg_err_t data_( byte const*& out );
private:
Zip7_Extractor_Impl* impl;
int index;
blargg_err_t extract_();
};
#endif

View File

@ -1,346 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Zip_Extractor.h"
#include "blargg_endian.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// To avoid copying filename string from catalog, I terminate it by modifying
// catalog data. This potentially requires moving the first byte of the type
// of the next entry elsewhere; I move it to the first byte of made_by. Kind
// of hacky, but I'd rather not have to allocate memory for a copy of it.
#include "blargg_source.h"
// Reads this much from end of file when first opening. Only this much is
// searched for the end catalog entry. If whole catalog is within this data,
// nothing more needs to be read on open.
int const end_read_size = 8 * 1024L;
// Reads are aligned to this size, increasing performance
int const disk_block_size = 4 * 1024L;
// Read buffer used for extracting file data
int const read_buf_size = 16 * 1024L;
struct header_t
{
char type [4];
byte vers [2];
byte flags [2];
byte method [2];
byte date [4];
byte crc [4];
byte raw_size [4];
byte size [4];
byte filename_len [2];
byte extra_len [2];
char filename [2]; // [filename_len]
//char extra [extra_len];
};
int const header_size = 30;
struct entry_t
{
char type [4];
byte made_by [2];
byte vers [2];
byte flags [2];
byte method [2];
byte date [4];
byte crc [4];
byte raw_size [4];
byte size [4];
byte filename_len [2];
byte extra_len [2];
byte comment_len [2];
byte disk [2];
byte int_attrib [2];
byte ext_attrib [4];
byte file_offset [4];
char filename [2]; // [filename_len]
//char extra [extra_len];
//char comment [comment_len];
};
int const entry_size = 46;
struct end_entry_t
{
char type [4];
byte disk [2];
byte first_disk [2];
byte disk_entry_count [2];
byte entry_count [2];
byte dir_size [4];
byte dir_offset [4];
byte comment_len [2];
char comment [2]; // [comment_len]
};
int const end_entry_size = 22;
Zip_Extractor::Zip_Extractor() : File_Extractor( fex_zip_type )
{
Zip_Extractor::clear_file_();
assert( offsetof (header_t,filename) == header_size );
assert( offsetof (entry_t,filename) == entry_size );
assert( offsetof (end_entry_t,comment) == end_entry_size );
}
extern "C" {
static File_Extractor* new_zip() { return BLARGG_NEW Zip_Extractor; }
}
fex_type_t_ const fex_zip_type [1] = {{ "ZIP", &new_zip }};
void Zip_Extractor::close_() { catalog.clear(); }
Zip_Extractor::~Zip_Extractor() { close(); }
void Zip_Extractor::open_filter_( const char*, Std_File_Reader* file )
{
file->make_unbuffered(); // faster since Zlib_Inflater already buffers data
}
blargg_err_t Zip_Extractor::open_()
{
file_size = file().size();
if ( file_size < end_entry_size )
return fex_wrong_file_type;
// Read end of file
long buf_offset = file_size - end_read_size;
if ( buf_offset < 0 )
buf_offset = 0;
buf_offset &= ~(disk_block_size - 1); // align beginning of read
RETURN_ERR( catalog.resize( file_size - buf_offset ) );
RETURN_ERR( file().seek( buf_offset ) );
RETURN_ERR( file().read( catalog.begin(), catalog.size() ) );
// Find end entry
int offset = catalog.size() - end_entry_size;
while ( memcmp( &catalog [offset], "PK\5\6", 4 ) )
{
if ( --offset < 0 )
return fex_wrong_file_type;
}
long end_offset = buf_offset + offset;
end_entry_t const& entry = (end_entry_t&) catalog [offset];
// some idiotic zip compressors add data to end of zip without setting comment len
check( file_size == end_offset + end_entry_size + get_le16( entry.comment_len ) );
// Find catalog offset
catalog_begin = get_le32( entry.dir_offset );
long catalog_size = end_offset - catalog_begin;
if ( catalog_size < 0 )
return buf.corrupt_error;
catalog_size += end_entry_size;
// Catalog might already be completely read
long begin_offset = catalog_begin - buf_offset;
if ( begin_offset >= 0 ) // all catalog data already in memory
memmove( catalog.begin(), &catalog [begin_offset], catalog_size );
RETURN_ERR( catalog.resize( catalog_size ) );
if ( begin_offset < 0 )
{
// Need to read catalog
RETURN_ERR( file().seek( catalog_begin ) );
RETURN_ERR( file().read( catalog.begin(), catalog.size() ) );
}
// first entry in catalog should be a file or end of archive
if ( memcmp( catalog.begin(), "PK\1\2", 4 ) && memcmp( catalog.begin(), "PK\5\6", 4 ) )
return fex_wrong_file_type;
// move first byte
catalog [4] = catalog [0];
catalog [0] = 0;
return rewind();
}
// Scanning
blargg_err_t Zip_Extractor::update_info( bool advance_first )
{
while ( 1 )
{
entry_t& e = (entry_t&) catalog [catalog_pos];
if ( memcmp( e.type, "\0K\1\2P", 5 ) )
{
check( !memcmp( e.type, "\0K\5\6P", 5 ) );
set_done();
break;
}
unsigned len = get_le16( e.filename_len );
long next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) +
get_le16( e.comment_len );
if ( (unsigned long) next_offset > catalog.size() - end_entry_size )
return buf.corrupt_error;
if ( catalog [next_offset] == 'P' )
{
// move first byte of type
catalog [next_offset] = 0;
catalog [next_offset + 4] = 'P';
}
if ( !advance_first )
{
e.filename [len] = 0; // terminate name
// Stop if not directory
long size = get_le32( e.size );
if ( size || (e.filename [len - 1] != '/' && e.filename [len - 1] != '\\') )
{
remain_ = size;
set_info( size, e.filename, get_le32( e.date ) );
break;
}
}
catalog_pos = next_offset;
advance_first = false;
}
return 0;
}
blargg_err_t Zip_Extractor::rewind_()
{
catalog_pos = 0;
return update_info( false );
}
blargg_err_t Zip_Extractor::next_()
{
return update_info( true );
}
// Reading
void Zip_Extractor::clear_file_()
{
remain_ = 0;
buf.end();
}
blargg_err_t Zip_Extractor::inflater_read( void* data, void* out, long* count )
{
Zip_Extractor& self = *(Zip_Extractor*) data;
if ( *count > self.raw_remain )
{
*count = self.raw_remain;
if ( !*count )
return 0;
}
self.raw_remain -= *count;
return self.file().read( out, *count );
}
long Zip_Extractor::remain() const { return remain_; }
blargg_err_t Zip_Extractor::fill_buf( long offset, long buf_size, long initial_read )
{
raw_remain = file_size - offset;
RETURN_ERR( file().seek( offset ) );
return buf.begin( inflater_read, this, buf_size, initial_read );
}
blargg_err_t Zip_Extractor::first_read( long count )
{
entry_t const& e = (entry_t&) catalog [catalog_pos];
method = get_le16( e.method );
if ( (method && method != Z_DEFLATED) || get_le16( e.vers ) > 20 )
return "Unsupported zip file compression";
long raw_size = get_le32( e.raw_size );
long file_offset = get_le32( e.file_offset );
int align = file_offset & (disk_block_size - 1);
{
// read header
long buf_size = 3 * disk_block_size - 1 + raw_size; // space for all raw data
buf_size &= ~(disk_block_size - 1);
long initial_read = buf_size;
if ( !method || count < size() )
{
buf_size = read_buf_size;
initial_read = disk_block_size * 2;
}
RETURN_ERR( fill_buf( file_offset - align, buf_size, initial_read ) );
}
header_t const& h = (header_t&) buf.data() [align];
if ( buf.filled() < align + header_size || memcmp( h.type, "PK\3\4", 4 ) )
return buf.corrupt_error;
// crc
correct_crc = get_le32( h.crc );
if ( !correct_crc )
correct_crc = get_le32( e.crc );
check( correct_crc == get_le32( e.crc ) ); // catalog CRC should match
crc = crc32( 0, 0, 0 );
// data offset
long data_offset = file_offset + header_size +
get_le16( h.filename_len ) + get_le16( h.extra_len );
if ( data_offset + raw_size > catalog_begin )
return buf.corrupt_error;
// refill buffer if there's lots of extra data after header
long buf_offset = data_offset - file_offset + align;
if ( buf_offset > buf.filled() )
{
// TODO: this will almost never occur, making it a good place for bugs
buf_offset = data_offset % disk_block_size;
RETURN_ERR( fill_buf( data_offset - buf_offset, read_buf_size, disk_block_size ) );
}
raw_remain = raw_size - (buf.filled() - buf_offset);
return buf.set_mode( (method ? buf.mode_raw_deflate : buf.mode_copy), buf_offset );
}
blargg_err_t Zip_Extractor::read( void* out, long count )
{
if ( count > remain_ )
return eof_error;
if ( count )
{
if ( remain_ == size() )
RETURN_ERR( first_read( count ) );
long actual = count;
RETURN_ERR( buf.read( out, &actual ) );
if ( actual < count )
return buf.corrupt_error;
crc = crc32( crc, (byte const*) out, count );
remain_ -= count;
if ( !remain_ && crc != correct_crc )
return buf.corrupt_error;
}
return 0;
}
blargg_err_t Zip_Extractor::read_once( void* out, long count )
{
require( remain_ == size() );
return read( out, count );
}

View File

@ -1,42 +0,0 @@
// ZIP archive extractor. Only supports deflation and store (no compression).
// File_Extractor 0.4.3
#ifndef ZIP_EXTRACTOR_H
#define ZIP_EXTRACTOR_H
#include "File_Extractor.h"
#include "Zlib_Inflater.h"
class Zip_Extractor : public File_Extractor {
public:
Zip_Extractor();
~Zip_Extractor();
blargg_err_t read( void*, long );
blargg_err_t read_once( void*, long );
long remain() const;
protected:
void open_filter_( const char*, Std_File_Reader* );
blargg_err_t open_();
blargg_err_t next_();
blargg_err_t rewind_();
void clear_file_();
void close_();
private:
blargg_vector<char> catalog;
long file_size;
long catalog_begin; // offset of first catalog entry in file (to detect corruption)
long catalog_pos; // position in catalog data
long raw_remain; // bytes remaining in raw data for current file
long remain_; // byres remaining to be extracted
unsigned long crc;
unsigned long correct_crc;
int method;
Zlib_Inflater buf;
blargg_err_t fill_buf( long offset, long buf_size, long initial_read );
blargg_err_t update_info( bool advance_first );
blargg_err_t first_read( long count );
static blargg_err_t inflater_read( void* data, void* out, long* count );
};
#endif

View File

@ -1,215 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "Zlib_Inflater.h"
#include <assert.h>
#include <string.h>
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
long const block_size = 4096;
const char Zlib_Inflater::corrupt_error [] = "Corrupt zip file";
static const char* get_zlib_err( int code )
{
assert( code != Z_OK );
if ( code == Z_MEM_ERROR )
return "Out of memory";
const char* str = zError( code );
if ( code == Z_DATA_ERROR )
str = Zlib_Inflater::corrupt_error;
if ( !str )
str = "Zip error";
return str;
}
void Zlib_Inflater::end()
{
if ( deflated_ )
{
deflated_ = false;
if ( inflateEnd( &zbuf ) )
check( false );
}
buf.clear();
static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
memcpy( &zbuf, &empty, sizeof zbuf );
}
Zlib_Inflater::Zlib_Inflater()
{
deflated_ = false;
end(); // initialize things
}
Zlib_Inflater::~Zlib_Inflater()
{
end();
}
blargg_err_t Zlib_Inflater::fill_buf( long count )
{
byte* out = buf.end() - count;
RETURN_ERR( callback( user_data, out, &count ) );
zbuf.avail_in = count;
zbuf.next_in = out;
return 0;
}
blargg_err_t Zlib_Inflater::begin( callback_t new_callback, void* new_user_data,
long new_buf_size, long initial_read )
{
callback = new_callback;
user_data = new_user_data;
end();
if ( !new_buf_size || (new_buf_size && buf.resize( new_buf_size )) )
{
RETURN_ERR( buf.resize( 4 * block_size ) );
initial_read = 0;
}
// Fill buffer with some data, less than normal buffer size since caller might
// just be examining beginning of file.
return fill_buf( initial_read ? initial_read : block_size );
}
blargg_err_t Zlib_Inflater::set_mode( mode_t mode, long data_offset )
{
zbuf.next_in += data_offset;
zbuf.avail_in -= data_offset;
if ( mode == mode_auto )
{
// examine buffer for gzip header
mode = mode_copy;
unsigned const min_gzip_size = 2 + 8 + 8;
if ( zbuf.avail_in >= min_gzip_size &&
zbuf.next_in [0] == 0x1F && zbuf.next_in [1] == 0x8B )
mode = mode_ungz;
}
if ( mode != mode_copy )
{
int wb = MAX_WBITS + 16; // have zlib handle gzip header
if ( mode == mode_raw_deflate )
wb = -MAX_WBITS;
int zerr = inflateInit2( &zbuf, wb );
if ( zerr )
{
zbuf.next_in = 0;
return get_zlib_err( zerr );
}
deflated_ = true;
}
return 0;
}
blargg_err_t Zlib_Inflater::read( void* out, long* count_io )
{
long remain = *count_io;
if ( remain && zbuf.next_in )
{
if ( deflated_ )
{
zbuf.next_out = (Bytef*) out;
zbuf.avail_out = remain;
while ( 1 )
{
uInt old_avail_in = zbuf.avail_in;
int err = inflate( &zbuf, Z_NO_FLUSH );
if ( err == Z_STREAM_END )
{
remain = zbuf.avail_out;
end();
break; // no more data to inflate
}
if ( err && (err != Z_BUF_ERROR || old_avail_in) )
return get_zlib_err( err );
if ( !zbuf.avail_out )
{
remain = 0;
break; // requested number of bytes inflate
}
if ( zbuf.avail_in )
{
// inflate() should never leave input if there's still space for output
assert( false );
return corrupt_error;
}
RETURN_ERR( fill_buf( buf.size() ) );
if ( !zbuf.avail_in )
return corrupt_error; // stream didn't end but there's no more data
}
}
else
{
while ( 1 )
{
// copy buffered data
if ( zbuf.avail_in )
{
long count = zbuf.avail_in;
if ( count > remain )
count = remain;
memcpy( out, zbuf.next_in, count );
zbuf.total_out += count;
out = (char*) out + count;
remain -= count;
zbuf.next_in += count;
zbuf.avail_in -= count;
}
if ( !zbuf.avail_in && zbuf.next_in < buf.end() )
{
end();
break;
}
// read large request directly
if ( remain + zbuf.total_out % block_size >= buf.size() )
{
long count = remain;
RETURN_ERR( callback( user_data, out, &count ) );
zbuf.total_out += count;
out = (char*) out + count;
remain -= count;
if ( remain )
{
end();
break;
}
}
if ( !remain )
break;
RETURN_ERR( fill_buf( buf.size() - zbuf.total_out % block_size ) );
}
}
}
*count_io -= remain;
return 0;
}

View File

@ -1,68 +0,0 @@
// Simplifies use of zlib for inflating data
// File_Extractor 0.4.3
#ifndef ZLIB_INFLATER_H
#define ZLIB_INFLATER_H
#include "blargg_common.h"
#include "zlib.h"
class Zlib_Inflater {
public:
static const char corrupt_error [];
// Data reader callback
typedef blargg_err_t (*callback_t)( void* user_data, void* out, long* count );
// Begins by setting callback and filling buffer. Default buffer is 16K and
// filled to 4K, or specify buf_size and initial_read for custom buffer size
// and how much to read initially.
blargg_err_t begin( callback_t, void* user_data,
long buf_size = 0, long initial_read = 0 );
// Data read into buffer by begin()
unsigned char const* data() const { return zbuf.next_in; }
long filled() const { return zbuf.avail_in; }
// Begins inflation using specified mode. Using mode_auto selects between
// mode_copy and mode_ungz by examining first two bytes of buffer. Use
// buf_offset to specify where data begins in buffer, in case there is
// header data that should be skipped.
enum mode_t { mode_copy, mode_ungz, mode_raw_deflate, mode_auto };
blargg_err_t set_mode( mode_t, long buf_offset = 0 );
// True if set_mode() has been called with mode_ungz or mode_raw_deflate
bool deflated() const { return deflated_; }
// Reads/inflates at most *count_io bytes into *out and sets *count_io to actual
// number of bytes read (less than requested if end of data was reached).
// Buffers source data internally, even in copy mode.
blargg_err_t read( void* out, long* count_io );
// Total number of bytes read since begin()
long tell() const { return zbuf.total_out; }
// Ends inflation and frees memory
void end();
private:
// noncopyable
Zlib_Inflater( const Zlib_Inflater& );
Zlib_Inflater& operator = ( const Zlib_Inflater& );
public:
Zlib_Inflater();
~Zlib_Inflater();
private:
z_stream_s zbuf;
blargg_vector<unsigned char> buf;
bool deflated_;
callback_t callback;
void* user_data;
blargg_err_t inflate_();
blargg_err_t fill_buf( long count );
};
#endif

View File

@ -1,155 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "abstract_file.h"
#include <string.h>
#include <stdio.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
Data_Writer::~Data_Writer() { }
// Std_File_Writer
Std_File_Writer::Std_File_Writer() : file_( 0 ) { }
Std_File_Writer::~Std_File_Writer() { close(); }
blargg_err_t Std_File_Writer::open( const char* path )
{
file_ = fopen( path, "wb" );
if ( !file_ )
return "Couldn't open file for writing";
// TODO: increase file buffer size?
//setvbuf( file_, 0, _IOFBF, 32 * 1024L );
return 0;
}
blargg_err_t Std_File_Writer::write( const void* p, long s )
{
long result = fwrite( p, 1, s, (FILE*) file_ );
if ( result != s )
return "Couldn't write to file";
return 0;
}
void Std_File_Writer::close()
{
if ( file_ )
{
fclose( (FILE*) file_ );
file_ = 0;
}
}
// Mem_Writer
Mem_Writer::Mem_Writer( void* p, long s, int b )
{
data_ = (char*) p;
size_ = 0;
allocated = s;
mode = b ? ignore_excess : fixed;
}
Mem_Writer::Mem_Writer()
{
data_ = 0;
size_ = 0;
allocated = 0;
mode = expanding;
}
Mem_Writer::~Mem_Writer()
{
if ( mode == expanding )
free( data_ );
}
blargg_err_t Mem_Writer::write( const void* p, long s )
{
long remain = allocated - size_;
if ( s > remain )
{
if ( mode == fixed )
return "Tried to write more data than expected";
if ( mode == ignore_excess )
{
s = remain;
}
else // expanding
{
long new_allocated = size_ + s;
new_allocated += (new_allocated >> 1) + 2048;
void* p = realloc( data_, new_allocated );
if ( !p )
return "Out of memory";
data_ = (char*) p;
allocated = new_allocated;
}
}
assert( size_ + s <= allocated );
memcpy( data_ + size_, p, s );
size_ += s;
return 0;
}
// Null_Writer
blargg_err_t Null_Writer::write( const void*, long ) { return 0; }
// Gzip_File_Writer
#ifdef HAVE_ZLIB_H
#include "zlib.h"
Gzip_File_Writer::Gzip_File_Writer() : file_( 0 ) { }
Gzip_File_Writer::~Gzip_File_Writer() { close(); }
blargg_err_t Gzip_File_Writer::open( const char* path, int level )
{
close();
char mode [4] = "wb\0";
if ( (unsigned) level <= 9 )
mode [2] = '0' + level;
file_ = gzopen( path, mode );
if ( !file_ )
return "Couldn't open file for writing";
return 0;
}
blargg_err_t Gzip_File_Writer::write( const void* p, long s )
{
if ( s != gzwrite( file_ , (void*) p, s ) )
return "Couldn't write to file";
return 0;
}
void Gzip_File_Writer::close()
{
if ( file_ )
{
gzclose( file_ );
file_ = 0;
}
}
#endif

View File

@ -1,91 +0,0 @@
// Lightweight interfaces for reading and writing data
// File_Extractor 0.4.3
#ifndef ABSTRACT_FILE_H
#define ABSTRACT_FILE_H
#include "blargg_common.h"
#include "Data_Reader.h"
// Supports writing
class Data_Writer {
public:
Data_Writer() { }
virtual ~Data_Writer();
// Writes 'n' bytes. Returns error if they couldn't all be written.
virtual blargg_err_t write( void const*, long n ) BLARGG_PURE( { (void) n; return 0; } )
public:
typedef blargg_err_t error_t; // deprecated
BLARGG_DISABLE_NOTHROW
private:
// noncopyable
Data_Writer( const Data_Writer& );
Data_Writer& operator = ( const Data_Writer& );
};
// Disk file
class Std_File_Writer : public Data_Writer {
public:
blargg_err_t open( const char* path );
void close();
public:
Std_File_Writer();
~Std_File_Writer();
blargg_err_t write( void const*, long );
private:
void* file_;
};
// Writes data to memory
class Mem_Writer : public Data_Writer {
public:
// Keeps all written data in expanding block of memory
Mem_Writer();
// Writes to fixed-size block of memory. If ignore_excess is false, returns
// error if more than 'size' data is written, otherwise ignores any excess.
Mem_Writer( void*, long size, int ignore_excess = 0 );
// Pointer to beginning of written data
char* data() { return data_; }
// Number of bytes written
long size() const { return size_; }
public:
~Mem_Writer();
blargg_err_t write( void const*, long );
private:
char* data_;
long size_;
long allocated;
enum { expanding, fixed, ignore_excess } mode;
};
// Written data is ignored
class Null_Writer : public Data_Writer {
public:
blargg_err_t write( void const*, long );
};
// Gzip compressor
#ifdef HAVE_ZLIB_H
class Gzip_File_Writer : public Data_Writer {
public:
// Compression level varies from 0 (min, fast) to 9 (max, slow). -1 = default.
blargg_err_t open( const char* path, int compression_level = -1 );
void close();
public:
Gzip_File_Writer();
~Gzip_File_Writer();
blargg_err_t write( const void*, long );
private:
void* file_;
};
#endif
#endif

View File

@ -1,206 +0,0 @@
// Sets up common environment for Shay Green's libraries.
// To change configuration options, modify blargg_config.h, not this file.
// File_Extractor 0.4.3
#ifndef BLARGG_COMMON_H
#define BLARGG_COMMON_H
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#undef BLARGG_COMMON_H
// allow blargg_config.h to #include blargg_common.h
#include "blargg_config.h"
#ifndef BLARGG_COMMON_H
#define BLARGG_COMMON_H
// BLARGG_RESTRICT: equivalent to restrict, where supported
#if __GNUC__ >= 3 || _MSC_VER >= 1100
#define BLARGG_RESTRICT __restrict
#else
#define BLARGG_RESTRICT
#endif
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
// CONST_CAST( T,expr): Used in place of const_cast<T> (expr)
#ifndef STATIC_CAST
#if __GNUC__ >= 4
#define STATIC_CAST(T,expr) static_cast<T> (expr)
#define CONST_CAST( T,expr) const_cast<T> (expr)
#else
#define STATIC_CAST(T,expr) ((T) (expr))
#define CONST_CAST( T,expr) ((T) (expr))
#endif
#endif
// blargg_err_t (0 on success, otherwise error string)
#ifndef blargg_err_t
typedef const char* blargg_err_t;
#endif
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
template<class T>
class blargg_vector {
T* begin_;
size_t size_;
public:
blargg_vector() : begin_( 0 ), size_( 0 ) { }
~blargg_vector() { free( begin_ ); }
size_t size() const { return size_; }
T* begin() const { return begin_; }
T* end() const { return begin_ + size_; }
blargg_err_t resize( size_t n )
{
// TODO: blargg_common.cpp to hold this as an outline function, ugh
void* p = realloc( begin_, n * sizeof (T) );
if ( p )
begin_ = (T*) p;
else if ( n > size_ ) // realloc failure only a problem if expanding
return "Out of memory";
size_ = n;
return 0;
}
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
T& operator [] ( size_t n ) const
{
assert( n <= size_ ); // <= to allow past-the-end value
return begin_ [n];
}
};
#ifndef BLARGG_DISABLE_NOTHROW
// throw spec mandatory in ISO C++ if operator new can return NULL
#if __cplusplus >= 199711 || __GNUC__ >= 3
#define BLARGG_THROWS( spec ) throw spec
#else
#define BLARGG_THROWS( spec )
#endif
#define BLARGG_DISABLE_NOTHROW \
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
void operator delete ( void* p ) { free( p ); }
#define BLARGG_NEW new
#else
#include <new>
#define BLARGG_NEW new (std::nothrow)
#endif
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
#define BLARGG_4CHAR( a, b, c, d ) \
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
#ifndef BOOST_STATIC_ASSERT
#ifdef _MSC_VER
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
#define BOOST_STATIC_ASSERT( expr ) \
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
#else
// Some other compilers fail when declaring same function multiple times in class,
// so differentiate them by line
#define BOOST_STATIC_ASSERT( expr ) \
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
#endif
#endif
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
// compiler is assumed to support bool. If undefined, availability is determined.
#ifndef BLARGG_COMPILER_HAS_BOOL
#if defined (__MWERKS__)
#if !__option(bool)
#define BLARGG_COMPILER_HAS_BOOL 0
#endif
#elif defined (_MSC_VER)
#if _MSC_VER < 1100
#define BLARGG_COMPILER_HAS_BOOL 0
#endif
#elif defined (__GNUC__)
// supports bool
#elif __cplusplus < 199711
#define BLARGG_COMPILER_HAS_BOOL 0
#endif
#endif
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
// If you get errors here, modify your blargg_config.h file
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
typedef long blargg_long;
#else
typedef int blargg_long;
#endif
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
typedef unsigned long blargg_ulong;
#else
typedef unsigned blargg_ulong;
#endif
// BOOST::int8_t etc.
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
#if defined (HAVE_STDINT_H)
#include <stdint.h>
#define BOOST
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
#elif defined (HAVE_INTTYPES_H)
#include <inttypes.h>
#define BOOST
#else
struct BOOST
{
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
typedef signed char int8_t;
typedef unsigned char uint8_t;
#else
// No suitable 8-bit type available
typedef struct see_blargg_common_h int8_t;
typedef struct see_blargg_common_h uint8_t;
#endif
#if USHRT_MAX == 0xFFFF
typedef short int16_t;
typedef unsigned short uint16_t;
#else
// No suitable 16-bit type available
typedef struct see_blargg_common_h int16_t;
typedef struct see_blargg_common_h uint16_t;
#endif
#if ULONG_MAX == 0xFFFFFFFF
typedef long int32_t;
typedef unsigned long uint32_t;
#elif UINT_MAX == 0xFFFFFFFF
typedef int int32_t;
typedef unsigned int uint32_t;
#else
// No suitable 32-bit type available
typedef struct see_blargg_common_h int32_t;
typedef struct see_blargg_common_h uint32_t;
#endif
};
#endif
#if __GNUC__ >= 3
#define BLARGG_DEPRECATED __attribute__ ((deprecated))
#else
#define BLARGG_DEPRECATED
#endif
// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib.
// During development, BLARGG_PURE( x ) expands to = 0;
// virtual int func() BLARGG_PURE( { return 0; } )
#ifndef BLARGG_PURE
#define BLARGG_PURE( def ) def
#endif
#endif
#endif

View File

@ -1,23 +0,0 @@
// Library configuration. Modify this file as necessary.
// File_Extractor 0.4.3
#ifndef BLARGG_CONFIG_H
#define BLARGG_CONFIG_H
// Uncomment to enable RAR archive support. Doing so adds extra licensing restrictions
// to this library (see unrar/readme.txt for more information).
//#define FEX_ENABLE_RAR 1
// Uncomment and edit to support only the listed archive types. See fex_type_list.cpp
// for a list of all types.
//#define FEX_TYPE_LIST fex_7z_type,fex_gz_type,fex_rar_type,fex_zip_type,fex_bin_type
// Uncomment if you get errors in the bool section of blargg_common.h
//#define BLARGG_COMPILER_HAS_BOOL 1
// Use standard config.h if present
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif

View File

@ -1,185 +0,0 @@
// CPU Byte Order Utilities
// File_Extractor 0.4.3
#ifndef BLARGG_ENDIAN
#define BLARGG_ENDIAN
#include "blargg_common.h"
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
#define BLARGG_CPU_X86 1
#define BLARGG_CPU_CISC 1
#endif
#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
defined (__POWERPC__) || defined (__powerc)
#define BLARGG_CPU_POWERPC 1
#define BLARGG_CPU_RISC 1
#endif
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
// one may be #defined to 1. Only needed if something actually depends on byte order.
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
#ifdef __GLIBC__
// GCC handles this for us
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define BLARGG_LITTLE_ENDIAN 1
#elif __BYTE_ORDER == __BIG_ENDIAN
#define BLARGG_BIG_ENDIAN 1
#endif
#else
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
#define BLARGG_LITTLE_ENDIAN 1
#endif
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
defined (__sparc__) || BLARGG_CPU_POWERPC || \
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
#define BLARGG_BIG_ENDIAN 1
#elif !defined (__mips__)
// No endian specified; assume little-endian, since it's most common
#define BLARGG_LITTLE_ENDIAN 1
#endif
#endif
#endif
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
#undef BLARGG_LITTLE_ENDIAN
#undef BLARGG_BIG_ENDIAN
#endif
inline void blargg_verify_byte_order()
{
#ifndef NDEBUG
#if BLARGG_BIG_ENDIAN
volatile int i = 1;
assert( *(volatile char*) &i == 0 );
#elif BLARGG_LITTLE_ENDIAN
volatile int i = 1;
assert( *(volatile char*) &i != 0 );
#endif
#endif
}
inline unsigned get_le16( void const* p )
{
return (unsigned) ((unsigned char const*) p) [1] << 8 |
(unsigned) ((unsigned char const*) p) [0];
}
inline unsigned get_be16( void const* p )
{
return (unsigned) ((unsigned char const*) p) [0] << 8 |
(unsigned) ((unsigned char const*) p) [1];
}
inline blargg_ulong get_le32( void const* p )
{
return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
(blargg_ulong) ((unsigned char const*) p) [2] << 16 |
(blargg_ulong) ((unsigned char const*) p) [1] << 8 |
(blargg_ulong) ((unsigned char const*) p) [0];
}
inline blargg_ulong get_be32( void const* p )
{
return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
(blargg_ulong) ((unsigned char const*) p) [1] << 16 |
(blargg_ulong) ((unsigned char const*) p) [2] << 8 |
(blargg_ulong) ((unsigned char const*) p) [3];
}
inline void set_le16( void* p, unsigned n )
{
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
((unsigned char*) p) [0] = (unsigned char) n;
}
inline void set_be16( void* p, unsigned n )
{
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
((unsigned char*) p) [1] = (unsigned char) n;
}
inline void set_le32( void* p, blargg_ulong n )
{
((unsigned char*) p) [0] = (unsigned char) n;
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
}
inline void set_be32( void* p, blargg_ulong n )
{
((unsigned char*) p) [3] = (unsigned char) n;
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
}
#if BLARGG_NONPORTABLE
// Optimized implementation if byte order is known
#if BLARGG_LITTLE_ENDIAN
#define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
#define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
#elif BLARGG_BIG_ENDIAN
#define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
#if BLARGG_CPU_POWERPC
// PowerPC has special byte-reversed instructions
#if defined (__MWERKS__)
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
#elif defined (__GNUC__)
#define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
#define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
#define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
#define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
#endif
#endif
#endif
#endif
#ifndef GET_LE16
#define GET_LE16( addr ) get_le16( addr )
#define SET_LE16( addr, data ) set_le16( addr, data )
#endif
#ifndef GET_LE32
#define GET_LE32( addr ) get_le32( addr )
#define SET_LE32( addr, data ) set_le32( addr, data )
#endif
#ifndef GET_BE16
#define GET_BE16( addr ) get_be16( addr )
#define SET_BE16( addr, data ) set_be16( addr, data )
#endif
#ifndef GET_BE32
#define GET_BE32( addr ) get_be32( addr )
#define SET_BE32( addr, data ) set_be32( addr, data )
#endif
// auto-selecting versions
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
#endif

View File

@ -1,92 +0,0 @@
/* Included at the beginning of library source files, AFTER all other #include lines.
Sets up helpful macros and services used in my source code. Since this is only "active"
in my source code, I don't have to worry about polluting the global namespace with
unprefixed names. */
// File_Extractor 0.4.3
#ifndef BLARGG_SOURCE_H
#define BLARGG_SOURCE_H
// The following four macros are for debugging only. Some or all might be defined
// to do nothing, depending on the circumstances. Described is what happens when
// a particular macro is defined to do something. When defined to do nothing, the
// macros do NOT evaluate their argument(s).
// If expr is false, prints file and line number, then aborts program. Meant for
// checking internal state and consistency. A failed assertion indicates a bug
// in MY code.
//
// void assert( bool expr );
#include <assert.h>
// If expr is false, prints file and line number, then aborts program. Meant for
// checking caller-supplied parameters and operations that are outside the control
// of the module. A failed requirement probably indicates a bug in YOUR code.
//
// void require( bool expr );
#undef require
#define require( expr ) assert( expr )
// Like printf() except output goes to debugging console/file.
//
// void dprintf( const char* format, ... );
static inline void blargg_dprintf_( const char*, ... ) { }
#undef dprintf
#define dprintf (1) ? (void) 0 : blargg_dprintf_
// If expr is false, prints file and line number to debug console/log, then
// continues execution normally. Meant for flagging potential problems or things
// that should be looked into, but that aren't serious problems.
//
// void check( bool expr );
#undef check
#define check( expr ) ((void) 0)
// If expr yields non-NULL error string, returns it from current function,
// otherwise continues normally.
#undef RETURN_ERR
#define RETURN_ERR( expr ) do { \
blargg_err_t blargg_return_err_ = (expr); \
if ( blargg_return_err_ ) return blargg_return_err_; \
} while ( 0 )
// If ptr is NULL, returns "Out of memory" error string, otherwise continues normally.
#undef CHECK_ALLOC
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
// The usual min/max functions for built-in types.
//
// template<typename T> T min( T x, T y ) { return x < y ? x : y; }
// template<typename T> T max( T x, T y ) { return x > y ? x : y; }
#define BLARGG_DEF_MIN_MAX( type ) \
static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\
static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; }
BLARGG_DEF_MIN_MAX( int )
BLARGG_DEF_MIN_MAX( unsigned )
BLARGG_DEF_MIN_MAX( long )
BLARGG_DEF_MIN_MAX( unsigned long )
BLARGG_DEF_MIN_MAX( float )
BLARGG_DEF_MIN_MAX( double )
#undef min
#define min blargg_min
#undef max
#define max blargg_max
// typedef unsigned char byte;
typedef unsigned char blargg_byte;
#undef byte
#define byte blargg_byte
// deprecated
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
#define BLARGG_RETURN_ERR RETURN_ERR
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
#ifdef BLARGG_SOURCE_BEGIN
#include BLARGG_SOURCE_BEGIN
#endif
#endif

View File

@ -1,188 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "fex.h"
#include "File_Extractor.h"
#include "blargg_endian.h"
#include <string.h>
#include <ctype.h>
/* Copyright (C) 2005-2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
#ifndef FEX_TYPE_LIST
// Archive types supported by default. If you want to change this list,
// modify the copy in blargg_config.h, NOT this one.
#if FEX_ENABLE_RAR
#define FEX_TYPE_LIST \
fex_7z_type, fex_gz_type, fex_zip_type, fex_bin_type
#else
#define FEX_TYPE_LIST \
fex_7z_type, fex_gz_type, fex_zip_type, fex_bin_type
#endif
#endif
static fex_type_t const fex_type_list_ [] = { FEX_TYPE_LIST, 0 };
fex_type_t const* fex_type_list() { return fex_type_list_; }
void fex_close( File_Extractor* fe ) { delete fe; }
void* fex_user_data ( File_Extractor const* fe ) { return fe->user_data(); }
void fex_set_user_data ( File_Extractor* fe, void* new_user_data ) { fe->set_user_data( new_user_data ); }
void fex_set_user_cleanup ( File_Extractor* fe, fex_user_cleanup_t func ) { fe->set_user_cleanup( func ); }
fex_type_t fex_type ( File_Extractor const* fe ) { return fe->type(); }
int fex_done ( File_Extractor const* fe ) { return fe->done(); }
const char* fex_name ( File_Extractor const* fe ) { return fe->name(); }
long fex_size ( File_Extractor const* fe ) { return fe->size(); }
unsigned long fex_dos_date ( File_Extractor const* fe ) { return fe->dos_date(); }
long fex_remain ( File_Extractor const* fe ) { return fe->remain(); }
fex_err_t fex_read ( File_Extractor* fe, void* out, long count ) { return fe->read( out, count ); }
long fex_read_avail ( File_Extractor* fe, void* out, long count ) { return fe->read_avail( out, count ); }
fex_err_t fex_read_once ( File_Extractor* fe, void* out, long count ) { return fe->read_once( out, count ); }
fex_err_t fex_next ( File_Extractor* fe ) { return fe->next(); }
fex_err_t fex_rewind ( File_Extractor* fe ) { return fe->rewind(); }
void fex_scan_only ( File_Extractor* fe ) { fe->scan_only(); }
const unsigned char* fex_data( File_Extractor* fe, fex_err_t* err_out )
{
blargg_err_t berr;
const unsigned char* p = fe->data( &berr );
if ( err_out )
*err_out = berr;
return p;
}
const char* fex_identify_header( void const* header )
{
unsigned long four = get_be32( header );
switch ( four )
{
case 0x52457E5E:
case 0x52617221: return "RAR";
case 0x377ABCAF: return "7Z";
case 0x504B0304:
case 0x504B0506: return "ZIP";
// TODO: also identify other archive types *not* supported?
// unsupported types, to avoid opening them in Single_File_Extractor
//case 0x53495421: return "SIT";
}
if ( (four >> 16) == 0x1F8B )
return "GZ";
return "";
}
static void to_uppercase( const char* in, int len, char* out )
{
for ( int i = 0; i < len; i++ )
{
if ( !(out [i] = toupper( in [i] )) )
return;
}
*out = 0; // extension too long
}
fex_type_t fex_identify_extension( const char* extension_ )
{
char const* end = strrchr( extension_, '.' );
if ( end )
extension_ = end + 1;
char extension [6];
to_uppercase( extension_, sizeof extension, extension );
fex_type_t result = 0;
for ( fex_type_t const* types = fex_type_list_; *types; types++ )
{
if ( !*(*types)->extension )
result = *types; // fex_bin_type, so use if nothing else matches
if ( !strcmp( extension, (*types)->extension ) )
return *types;
}
return result;
}
static fex_err_t fex_identify_file_( const char* path, fex_type_t* type_out )
{
*type_out = fex_identify_extension( path );
if ( !*type_out || !strrchr( path, '.' ) )
{
*type_out = 0;
FEX_FILE_READER in;
RETURN_ERR( in.open( path ) );
char header [4] = { 0 };
if ( in.read_avail( header, sizeof header ) < 0 )
return "Couldn't read file";
*type_out = fex_identify_extension( fex_identify_header( header ) );
}
return 0;
}
fex_type_t fex_identify_file( const char* path, fex_err_t* err_out )
{
fex_type_t type;
fex_err_t err = fex_identify_file_( path, &type );
if ( err_out )
*err_out = err;
return type;
}
static fex_err_t fex_open_type_( fex_type_t type, const char* path, File_Extractor** fe_out )
{
*fe_out = 0;
if ( !type )
return fex_wrong_file_type;
File_Extractor* fe = type->new_fex();
CHECK_ALLOC( fe );
fex_err_t err = fe->open( path );
if ( err )
{
delete fe;
return err;
}
*fe_out = fe;
return 0;
}
File_Extractor* fex_open_type( fex_type_t type, const char* path, fex_err_t* err_out )
{
File_Extractor* fe;
fex_err_t err = fex_open_type_( type, path, &fe );
if ( err_out )
*err_out = err;
return fe;
}
File_Extractor* fex_open( const char* path, fex_err_t* err_out )
{
fex_type_t type = fex_identify_file( path, err_out );
if ( !type )
return 0;
return fex_open_type( type, path, err_out );
}

View File

@ -1,140 +0,0 @@
/* Compressed file archive C interface (also usable from C++) */
/* File_Extractor 0.4.3 */
#ifndef FEX_H
#define FEX_H
#ifdef __cplusplus
extern "C" {
#endif
/* Error string returned by library functions, or NULL if no error (success).
If function takes fex_err_t* err_out, it sets *err_out to NULL on success,
otherwise error string, or you can pass NULL if you don't care about exact
cause of error (these functions still report error by returning NULL). */
typedef const char* fex_err_t;
/* First parameter of most extractor_ functions is a pointer to the
File_Extractor being acted on. */
typedef struct File_Extractor File_Extractor;
/**** Basics ****/
/* Opens archive and returns pointer to it, or NULL if error. */
File_Extractor* fex_open( const char* path, fex_err_t* err_out );
/* True if at end of archive. */
int fex_done( File_Extractor const* );
/* Name of current file. */
const char* fex_name( File_Extractor const* );
/* Size of current file. */
long fex_size( File_Extractor const* );
/* Extracts n bytes and writes them to *out. Returns error if all n
bytes couldn't be extracted (due to end of file or read error). */
fex_err_t fex_read( File_Extractor*, void* out, long n );
/* Goes to next file in archive (skips directories). */
fex_err_t fex_next( File_Extractor* );
/* Closes archive and frees memory. */
void fex_close( File_Extractor* );
/**** Advanced ****/
/* Goes back to first file in archive. */
fex_err_t fex_rewind( File_Extractor* );
/* Hints to fex_next() that no file extraction will occur, speeding scanning
of some archive types. */
void fex_scan_only( File_Extractor* );
/* Modification date of current file (MS-DOS format). */
unsigned long fex_dos_date( File_Extractor const* );
/* Number of bytes remaining to be read from current file. */
long fex_remain( File_Extractor const* );
/* Reads at most n bytes and returns number actually read, or negative if error. */
long fex_read_avail( File_Extractor*, void* out, long n );
/* Extracts first n bytes and ignores rest. Faster than a normal read since it
doesn't need to read any more data. Must not be called twice in a row. */
fex_err_t fex_read_once( File_Extractor*, void* out, long n );
/* Loads file data into memory (if not already) and returns pointer to it, or
NULL if error. Pointer is valid until fex_next(), fex_rewind(), or fex_close() are
called. Will return same pointer if called more than once. */
const unsigned char* fex_data( File_Extractor*, fex_err_t* err_out );
/**** Archive types ****/
/* fex_type_t is a pointer to this structure. For example, fex_zip_type->extension is
"ZIP" and ex_zip_type->new_fex() is equilvant to 'new Zip_Extractor' (in C++). */
struct fex_type_t_
{
const char* extension; /* file extension/type */
File_Extractor* (*new_fex)();
};
/* Archive type constants for each supported file type */
extern struct fex_type_t_ const
fex_7z_type [1], /* .7z (7-zip) */
fex_gz_type [1], /* .gz (gzip) */
/*fex_rar_type [1],*/ /* .rar */
fex_zip_type [1], /* .zip */
fex_bin_type [1]; /* binary file, possibly gzipped */
typedef struct fex_type_t_ const* fex_type_t;
/* Array of supported archive types, with NULL entry at end. */
fex_type_t const* fex_type_list();
/* Type of archive this extractor handles. */
fex_type_t fex_type( File_Extractor const* );
/******** Advanced opening ********/
/* Error returned if file is wrong type */
extern const char fex_wrong_file_type [29];
/* Determines likely archive type based on first four bytes of file. Returns string
containing proper file suffix (i.e. "ZIP", "GZ", etc.) or "" (empty string) if file
header is not recognized. */
const char* fex_identify_header( void const* header );
/* Gets corresponding archive type for file path or extension passed in. Returns NULL
if type isn't recognized. */
fex_type_t fex_identify_extension( const char* path_or_extension );
/* Determines file type based on filename extension, or file header (if extension
isn't recognized). Returns NULL if unrecognized or error. */
fex_type_t fex_identify_file( const char* path, fex_err_t* err_out );
/* Opens archive of specific type and returns pointer to it, or NULL if error. */
File_Extractor* fex_open_type( fex_type_t, const char* path, fex_err_t* err_out );
/******** User data ********/
/* Sets/gets pointer to data you want to associate with this extractor.
You can use this for whatever you want. */
void fex_set_user_data( File_Extractor*, void* new_user_data );
void* fex_user_data( File_Extractor const* );
/* Registers cleanup function to be called when closing extractor, or NULL to
clear it. Passes user_data (see above) to cleanup function. */
typedef void (*fex_user_cleanup_t)( void* user_data );
void fex_set_user_cleanup( File_Extractor*, fex_user_cleanup_t func );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,175 +0,0 @@
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "unzip.h"
#include "File_Extractor.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
/* Copyright (C) 2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
// log error message to stderr when debugging
inline unzError log_error( const char* str )
{
if ( !str )
return UNZ_OK;
#ifndef NDEBUG
fprintf( stderr, "unzip Error: %s\n", str );
#endif
return UNZ_INTERNALERROR;
}
int unzStringFileNameCompare( const char* x, const char* y, int case_sensitive )
{
if ( !case_sensitive )
{
case_sensitive = 1;
#if !defined (unix)
case_sensitive = 2;
#endif
}
if ( case_sensitive == 1 )
return strcmp( x, y );
int xx, yy;
do
{
xx = tolower( *x++ );
yy = tolower( *y++ );
}
while ( yy && xx == yy );
return xx - yy;
}
unzFile unzOpen( const char* path )
{
fex_err_t err;
File_Extractor* fex = fex_open( path, &err );
if ( log_error( err ) )
return 0;
fex->scan_only();
return fex;
}
unzError unzClose( unzFile fex )
{
delete fex;
return UNZ_OK;
}
unzError unzGoToFirstFile( unzFile fex )
{
unzError err = log_error( fex->rewind() );
if ( !err && fex->done() )
err = UNZ_BADZIPFILE; // unzip interface can't handle an empty file
fex->scan_only();
return err;
}
unzError unzGoToNextFile( unzFile fex )
{
if ( fex->done() )
return UNZ_END_OF_LIST_OF_FILE;
unzError err = log_error( fex->next() );
if ( !err && fex->done() )
err = UNZ_END_OF_LIST_OF_FILE;
return err;
}
unzError unzLocateFile( unzFile fex, const char* name, int case_sensitive )
{
unzError err = unzGoToFirstFile( fex );
if ( !err )
{
fex->scan_only( false ); // user is likely to extract file
do
{
if ( !unzStringFileNameCompare( fex->name(), name, case_sensitive ) )
return UNZ_OK;
}
while ( (err = unzGoToNextFile( fex )) == 0 );
}
return err;
}
unzError unzGetCurrentFileInfo( unzFile fex, unz_file_info* info_out,
char* filename_out, uLong filename_size,
void* extra_out, uLong, char* comment_out, uLong )
{
// extra and comment aren't supported
assert( !extra_out && !comment_out );
memset( info_out, 0, sizeof *info_out );
if ( fex->done() )
return UNZ_END_OF_LIST_OF_FILE;
size_t name_len = strlen( fex->name() );
if ( info_out )
{
info_out->uncompressed_size = fex->size();
info_out->size_filename = name_len;
info_out->dosDate = fex->dos_date();
}
if ( filename_out )
{
if ( filename_size <= name_len )
return UNZ_PARAMERROR;
strcpy( filename_out, fex->name() );
}
return UNZ_OK;
}
unzError unzOpenCurrentFile( unzFile fex )
{
if ( fex->done() )
return UNZ_END_OF_LIST_OF_FILE;
// fails if you try to re-open file again (I can add support if necessary)
assert( fex->remain() == fex->size() );
// fex automatically opens on first read
return UNZ_OK;
}
unzError unzReadCurrentFile( unzFile fex, void* out, unsigned count )
{
long actual = fex->read_avail( out, count );
if ( actual < 0 )
return UNZ_INTERNALERROR;
return (unzError) actual;
}
z_off_t unztell( unzFile fex )
{
return fex->size() - fex->remain();
}
int unzeof( unzFile fex )
{
return !fex->remain();
}
unzError unzCloseCurrentFile( unzFile )
{
// fex automatically closes
return UNZ_OK;
}

View File

@ -1,109 +0,0 @@
/* Accesses file archives using basic unzip 1.01e library interface functions.
With this you can use File_Extractor in place of the unzip library with minimal
changes to your code. If you're writing new code, use the fex.h interface. */
/* File_Extractor 0.4.3 */
#ifndef _unz_H
#define _unz_H
/* Your code can check for this to know to support other archive types */
#define FEX_WRAPPER 1
#include "zlib.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int unzError;
#define UNZ_OK 0
#define UNZ_END_OF_LIST_OF_FILE -100
#define UNZ_ERRNO Z_ERRNO
#define UNZ_EOF 0
#define UNZ_PARAMERROR -102
#define UNZ_BADZIPFILE -103
#define UNZ_INTERNALERROR -104
#define UNZ_CRCERROR -105
typedef struct File_Extractor* unzFile;
/* Only indicated fields are supported; all others are set to 0 (and
named with a trailing _ so your code won't compile if it uses them). */
typedef struct tm_unz_s
{
uInt tm_sec_;
uInt tm_min_;
uInt tm_hour_;
uInt tm_mday_;
uInt tm_mon_;
uInt tm_year_;
} tm_unz;
typedef struct unz_file_info_s
{
uLong version_;
uLong version_needed_;
uLong flag_;
uLong compression_method_;
uLong dosDate; /* supported */
uLong crc_;
uLong compressed_size_;
uLong uncompressed_size; /* supported */
uLong size_filename; /* supported */
uLong size_file_extra_;
uLong size_file_comment_;
uLong disk_num_start_;
uLong internal_fa_;
uLong external_fa_;
tm_unz tmu_date_;
} unz_file_info;
/* Opens file archive or returns NULL if error */
unzFile unzOpen( const char* path );
/* Goes to first file in archive */
unzError unzGoToFirstFile( unzFile );
/* Goes to next file in archive */
unzError unzGoToNextFile( unzFile );
/* Scans for file of given name and returns UNZ_OK if found */
unzError unzLocateFile( unzFile, const char* name, int case_sensitive );
/* Compares two strings with optional case sensitivity */
int unzStringFileNameCompare( const char* x, const char* y, int case_sensitive );
/* Gets name and size of current file. Doesn't support extra_out and
comment_out. */
unzError unzGetCurrentFileInfo( unzFile, unz_file_info* info_out,
char* filename_out, uLong filename_size,
void* extra_out, uLong extra_size,
char* comment_out, uLong comment_size );
/* Prepares to read data from current file */
unzError unzOpenCurrentFile( unzFile );
/* Reads at most 'count' bytes from current file into 'out' and returns number of
bytes actually read. Returns UNZ_EOF if end of file is reached, negative if error. */
unzError unzReadCurrentFile( unzFile, void* out, unsigned count );
/* Number of bytes read from current file */
z_off_t unztell( unzFile );
/* True if end of file has been reached */
int unzeof( unzFile );
/* Finishes reading from current file */
unzError unzCloseCurrentFile( unzFile );
/* Closes a file archive and frees memory */
unzError unzClose( unzFile );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,222 +0,0 @@
// Minimal implementation of fex.h. Supports gzipped files if you have zlib
// available and HAVE_ZLIB_H is defined.
// File_Extractor 0.4.3. http://www.slack.net/~ant/
#include "fex.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* Copyright (C) 2007 Shay Green. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef HAVE_ZLIB_H
#define FILE_GZ( norm, gz ) norm
#define FILE_READ( ptr, size, file ) fread( ptr, 1, size, file )
#else
#define FILE_GZ( norm, gz ) gz
#define FILE_READ( ptr, size, file ) gzread( file, ptr, size )
#include "zlib.h"
static const char* get_gzip_size( const char* path, long* eof )
{
FILE* file = fopen( path, "rb" );
if ( !file )
return "Couldn't open file";
unsigned char buf [4];
if ( fread( buf, 2, 1, file ) > 0 && buf [0] == 0x1F && buf [1] == 0x8B )
{
fseek( file, -4, SEEK_END );
fread( buf, 4, 1, file );
*eof = buf [3] * 0x1000000 + buf [2] * 0x10000 + buf [1] * 0x100 + buf [0];
}
else
{
fseek( file, 0, SEEK_END );
*eof = ftell( file );
}
const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0;
fclose( file );
return err;
}
#endif
const char fex_wrong_file_type [] = "Archive format not supported";
struct File_Extractor
{
FILE_GZ(FILE*,gzFile) file;
int done;
long size;
void* data; // file data read into memory, ot 0 if not read
void* user_data;
fex_user_cleanup_t user_cleanup;
char* name() { return (char*) (this + 1); }
};
// Always identify as single file extractor
fex_type_t_ const fex_bin_type [1] = {{ "" , 0 }};
const char* fex_identify_header ( void const* ) { return ""; }
fex_type_t fex_identify_extension( const char* ) { return fex_bin_type; }
fex_type_t fex_identify_file ( const char*, fex_err_t* e ) { if ( e ) *e = 0; return fex_bin_type; }
static fex_err_t fex_open_( const char* path, File_Extractor** fe_out )
{
*fe_out = 0;
// name
const char* name = strrchr( path, '\\' ); // DOS
if ( !name )
name = strrchr( path, '/' ); // UNIX
if ( !name )
name = strrchr( path, ':' ); // Mac
if ( !name )
name = path;
// allocate space for struct and name
long name_size = strlen( name ) + 1;
File_Extractor* fe = (File_Extractor*) malloc( sizeof (File_Extractor) + name_size );
if ( !fe ) return "Out of memory";
fe->done = 0;
fe->data = 0;
fe->user_data = 0;
fe->user_cleanup = 0;
memcpy( fe->name(), name, name_size );
#ifdef HAVE_ZLIB_H
// get gzip size BEFORE opening file
const char* err = get_gzip_size( path, &fe->size );
if ( err )
{
free( fe );
return err;
}
#endif
// open file
fe->file = FILE_GZ(fopen,gzopen)( path, "rb" );
if ( !fe->file )
{
free( fe );
return "Couldn't open file";
}
// get normal size
#ifndef HAVE_ZLIB_H
fseek( fe->file, 0, SEEK_END );
fe->size = ftell( fe->file );
rewind( fe->file );
#endif
*fe_out = fe;
return 0;
}
File_Extractor* fex_open( const char* path, fex_err_t* err_out )
{
File_Extractor* fe;
fex_err_t err = fex_open_( path, &fe );
if ( err_out )
*err_out = err;
return fe;
}
File_Extractor* fex_open_type( fex_type_t, const char* path, fex_err_t* err_out )
{
return fex_open( path, err_out );
}
void* fex_user_data ( File_Extractor const* fe ) { return fe->user_data; }
void fex_set_user_data ( File_Extractor* fe, void* new_user_data ) { fe->user_data = new_user_data; }
void fex_set_user_cleanup ( File_Extractor* fe, fex_user_cleanup_t func ) { fe->user_cleanup = func; }
fex_type_t fex_type ( File_Extractor const* ) { return fex_bin_type; }
int fex_done ( File_Extractor const* fe ) { return fe->done; }
const char* fex_name ( File_Extractor const* fe ) { return fe->name(); }
unsigned long fex_dos_date ( File_Extractor const* ) { return 0; }
long fex_size ( File_Extractor const* fe ) { return fe->size; }
long fex_remain ( File_Extractor const* fe ) { return fe->size - FILE_GZ(ftell,gztell)( fe->file ); }
void fex_scan_only ( File_Extractor* ) { }
fex_err_t fex_read_once ( File_Extractor* fe, void* out, long count ) { return fex_read( fe, out, count ); }
long fex_read_avail ( File_Extractor* fe, void* out, long count ) { return FILE_READ( out, count, fe->file ); }
fex_err_t fex_read( File_Extractor* fe, void* out, long count )
{
if ( count == (long) FILE_READ( out, count, fe->file ) )
return 0;
if ( FILE_GZ(feof,gzeof)( fe->file ) )
return "Unexpected end of file";
return "Couldn't read from file";
}
fex_err_t fex_next( File_Extractor* fe )
{
fe->done = 1;
return 0;
}
fex_err_t fex_rewind( File_Extractor* fe )
{
fe->done = 0;
FILE_GZ(rewind,gzrewind)( fe->file );
return 0;
}
static fex_err_t fex_data_( File_Extractor* fe )
{
if ( !fe->data )
{
fe->data = malloc( fe->size );
if ( !fe->data ) return "Out of memory";
fex_err_t err = fex_read( fe, fe->data, fe->size );
if ( err )
{
free( fe->data );
return err;
}
}
return 0;
}
const unsigned char* fex_data( File_Extractor* fe, fex_err_t* err_out )
{
fex_err_t err = fex_data_( fe );
if ( err_out )
*err_out = err;
return (const unsigned char*) fe->data;
}
void fex_close( File_Extractor* fe )
{
if ( fe )
{
free( fe->data );
FILE_GZ(fclose,gzclose)( fe->file );
if ( fe->user_cleanup )
fe->user_cleanup( fe->user_data );
free( fe );
}
}

View File

@ -1,504 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,18 +0,0 @@
# I don't compile zlib into fex.a since most systems have a native version.
# RAR support must be enabled in blargg_config.h.
all: libfex.a demo.exe
libfex.a: fex/fex.h fex/blargg_config.h
cd fex;$(CXX) -I.. -c -Os -fno-rtti -fno-exceptions *.cpp
cd 7z_C;$(CC) -c -Os *.c
cd 7z_C;$(CC) -c -Os *.c Archive/7z/*.c Compress/Branch/*.c Compress/Lzma/*.c
$(AR) $(ARFLAGS) libfex.a fex/*.o 7z_C/*.o
-ranlib libfex.a
demo.exe: demo.c libfex.a
$(CC) -o demo.exe -I. -lz demo.c libfex.a
clean:
-$(RM) fex/*.o 7z_C/*.o
-$(RM) libfex.a demo.exe

View File

@ -1,95 +0,0 @@
File_Extractor 0.4.3
--------------------
File_Extractor provides uniform access to files in popular compressed
archive formats. It is meant for programs which want to transparently
read from compressed files. Wrappers are also included that make the
library act like the unzip and unrarlib libraries, allowing your code to
work with minimal changes if you already use one of these libraries.
Features:
* C and C++ interfaces
* Supports ZIP, GZIP, 7-Zip (7Z), and RAR(*) archive formats
* File data can be extracted in several ways
* Uncompressed files can be treated as archives, simplifying your code
* Modular design allows removal of support for unneeded archive formats
(*) RAR support must be enabled before use, due to its special
licensing.
Author : Shay Green <gblargg@gmail.com>
Website : http://www.slack.net/~ant/
License : GNU Lesser General Public License (LGPL) for all except RAR
Language: C or C++
Getting Started
---------------
Build demo.exe by typing "make" at the command-line. If that doesn't
work, manually build a program from demo.c, fex/*.cpp, 7z_C/*.c, and
zlib/*.c. Be sure "test.zip" is in the same directory. Running the
program should list the files and content of the test.zip archive.
To enable RAR support, edit fex/blargg_config.h.
See fex.h for reference and fex.txt for documentation.
Files
-----
fex.txt Manual
changes.txt Change log
license.txt LGPL license
makefile Builds libfex.a and demo.exe
demo.c Basic library usage
test.zip Test archive used by demo
fex_mini.cpp Minimal version (no other sources needed)
fex/
blargg_config.h Configuration (modify as needed)
fex.h C interface (also usable from C++)
File_Extractor.h C++ interface
unzip.h Makes library act like unzip library
unzip.cpp
unrarlib.h Makes library act like unrarlib
unrarlib.cpp
Single_File_Extractor.h Single file support
Single_File_Extractor.cpp
Gzip_Reader.h
Gzip_Reader.cpp
Zip_Extractor.h Zip support
Zip_Extractor.cpp
Zip7_Extractor.h 7-Zip support
Zip7_Extractor.cpp
Rar_Extractor.h RAR support
Rar_Extractor.cpp
blargg_common.h Required
blargg_endian.h
blargg_source.h
abstract_file.h
abstract_file.cpp
Data_Reader.h
Data_Reader.cpp
File_Extractor.cpp
Zlib_Inflater.cpp
Zlib_Inflater.h
fex.cpp
zlib/ Gzip support (or use standard zlib)
7z_C/ 7-Zip support
unrar/ RAR support
--
Shay Green <gblargg@gmail.com>

Binary file not shown.

29
dependencies/LICENSE vendored
View File

@ -1,29 +0,0 @@
NASM is now licensed under the 2-clause BSD license, also known as the
simplified BSD license.
Copyright 1996-2009 the NASM Authors - All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,248 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="SFML_Network"
ProjectGUID="{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
RootNamespace="sfml-network"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)\$(ConfigurationName)\$(PlatformName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SFML_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)\$(ProjectName).lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)\$(ConfigurationName)\$(PlatformName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;SFML_EXPORTS;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
UsePrecompiledHeader="0"
WarningLevel="4"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)\$(ProjectName).lib"
/>
<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="..\..\src\SFML\Network\Win32\SocketHelper.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Win32\SocketHelper.hpp"
>
</File>
</Filter>
<File
RelativePath="..\..\src\SFML\Network\Ftp.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Ftp.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\Http.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Http.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\IPAddress.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\IPAddress.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\Packet.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Packet.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Selector.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\Selector.inl"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\SelectorBase.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\SelectorBase.hpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\SocketHelper.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\SocketTCP.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\SocketTCP.hpp"
>
</File>
<File
RelativePath="..\..\src\SFML\Network\SocketUDP.cpp"
>
</File>
<File
RelativePath="..\..\include\SFML\Network\SocketUDP.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="9.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="GOLIATH"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="GOLIATH"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,165 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_CONFIG_HPP
#define SFML_CONFIG_HPP
////////////////////////////////////////////////////////////
// Identify the operating system
////////////////////////////////////////////////////////////
#if defined(_WIN32) || defined(__WIN32__)
// Windows
#define SFML_SYSTEM_WINDOWS
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#elif defined(linux) || defined(__linux)
// Linux
#define SFML_SYSTEM_LINUX
#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)
// MacOS
#define SFML_SYSTEM_MACOS
#elif defined(__FreeBSD__)
// FreeBSD
#define SFML_SYSTEM_FREEBSD
#else
// Unsupported system
#error This operating system is not supported by SFML library
#endif
////////////////////////////////////////////////////////////
// Define a portable debug macro
////////////////////////////////////////////////////////////
#if !defined(NDEBUG)
#define SFML_DEBUG
#endif
////////////////////////////////////////////////////////////
// Define portable import / export macros
////////////////////////////////////////////////////////////
#if defined(SFML_SYSTEM_WINDOWS)
#ifdef SFML_DYNAMIC
// Windows platforms
#ifdef SFML_EXPORTS
// From DLL side, we must export
#define SFML_API __declspec(dllexport)
#else
// From client application side, we must import
#define SFML_API __declspec(dllimport)
#endif
// For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
// You can read lots ot different things about it, but the point is the code will
// just work fine, and so the simplest way to get rid of this warning is to disable it
#ifdef _MSC_VER
#pragma warning(disable : 4251)
#endif
#else
// No specific directive needed for static build
#define SFML_API
#endif
#else
// Other platforms don't need to define anything
#define SFML_API
#endif
////////////////////////////////////////////////////////////
// Define portable fixed-size types
////////////////////////////////////////////////////////////
#include <climits>
namespace sf
{
// 8 bits integer types
#if UCHAR_MAX == 0xFF
typedef signed char Int8;
typedef unsigned char Uint8;
#else
#error No 8 bits integer type for this platform
#endif
// 16 bits integer types
#if USHRT_MAX == 0xFFFF
typedef signed short Int16;
typedef unsigned short Uint16;
#elif UINT_MAX == 0xFFFF
typedef signed int Int16;
typedef unsigned int Uint16;
#elif ULONG_MAX == 0xFFFF
typedef signed long Int16;
typedef unsigned long Uint16;
#else
#error No 16 bits integer type for this platform
#endif
// 32 bits integer types
#if USHRT_MAX == 0xFFFFFFFF
typedef signed short Int32;
typedef unsigned short Uint32;
#elif UINT_MAX == 0xFFFFFFFF
typedef signed int Int32;
typedef unsigned int Uint32;
#elif ULONG_MAX == 0xFFFFFFFF
typedef signed long Int32;
typedef unsigned long Uint32;
#else
#error No 32 bits integer type for this platform
#endif
} // namespace sf
#endif // SFML_CONFIG_HPP

View File

@ -1,42 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_NETWORK_HPP
#define SFML_NETWORK_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System.hpp>
#include <SFML/Network/Ftp.hpp>
#include <SFML/Network/Http.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/Packet.hpp>
#include <SFML/Network/Selector.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/SocketUDP.hpp>
#endif // SFML_NETWORK_HPP

View File

@ -1,448 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_FTP_HPP
#define SFML_FTP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <string>
#include <vector>
namespace sf
{
class IPAddress;
////////////////////////////////////////////////////////////
/// This class provides methods for manipulating the FTP
/// protocol (described in RFC 959).
/// It provides easy access and transfers to remote
/// directories and files on a FTP server
////////////////////////////////////////////////////////////
class SFML_API Ftp : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// Enumeration of transfer modes
////////////////////////////////////////////////////////////
enum TransferMode
{
Binary, ///< Binary mode (file is transfered as a sequence of bytes)
Ascii, ///< Text mode using ASCII encoding
Ebcdic ///< Text mode using EBCDIC encoding
};
////////////////////////////////////////////////////////////
/// This class wraps a FTP response, which is basically :
/// - a status code
/// - a message
////////////////////////////////////////////////////////////
class SFML_API Response
{
public :
////////////////////////////////////////////////////////////
/// Enumerate all the valid status codes returned in
/// a FTP response
////////////////////////////////////////////////////////////
enum Status
{
// 1xx: the requested action is being initiated,
// expect another reply before proceeding with a new command
RestartMarkerReply = 110, ///< Restart marker reply
ServiceReadySoon = 120, ///< Service ready in N minutes
DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting
OpeningDataConnection = 150, ///< File status ok, about to open data connection
// 2xx: the requested action has been successfully completed
Ok = 200, ///< Command ok
PointlessCommand = 202, ///< Command not implemented
SystemStatus = 211, ///< System status, or system help reply
DirectoryStatus = 212, ///< Directory status
FileStatus = 213, ///< File status
HelpMessage = 214, ///< Help message
SystemType = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document
ServiceReady = 220, ///< Service ready for new user
ClosingConnection = 221, ///< Service closing control connection
DataConnectionOpened = 225, ///< Data connection open, no transfer in progress
ClosingDataConnection = 226, ///< Closing data connection, requested file action successful
EnteringPassiveMode = 227, ///< Entering passive mode
LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate
FileActionOk = 250, ///< Requested file action ok
DirectoryOk = 257, ///< PATHNAME created
// 3xx: the command has been accepted, but the requested action
// is dormant, pending receipt of further information
NeedPassword = 331, ///< User name ok, need password
NeedAccountToLogIn = 332, ///< Need account for login
NeedInformation = 350, ///< Requested file action pending further information
// 4xx: the command was not accepted and the requested action did not take place,
// but the error condition is temporary and the action may be requested again
ServiceUnavailable = 421, ///< Service not available, closing control connection
DataConnectionUnavailable = 425, ///< Can't open data connection
TransferAborted = 426, ///< Connection closed, transfer aborted
FileActionAborted = 450, ///< Requested file action not taken
LocalError = 451, ///< Requested action aborted, local error in processing
InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable
// 5xx: the command was not accepted and
// the requested action did not take place
CommandUnknown = 500, ///< Syntax error, command unrecognized
ParametersUnknown = 501, ///< Syntax error in parameters or arguments
CommandNotImplemented = 502, ///< Command not implemented
BadCommandSequence = 503, ///< Bad sequence of commands
ParameterNotImplemented = 504, ///< Command not implemented for that parameter
NotLoggedIn = 530, ///< Not logged in
NeedAccountToStore = 532, ///< Need account for storing files
FileUnavailable = 550, ///< Requested action not taken, file unavailable
PageTypeUnknown = 551, ///< Requested action aborted, page type unknown
NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation
FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed
// 10xx: SFML custom codes
InvalidResponse = 1000, ///< Response is not a valid FTP one
ConnectionFailed = 1001, ///< Connection with server failed
ConnectionClosed = 1002, ///< Connection with server closed
InvalidFile = 1003 ///< Invalid file to upload / download
};
////////////////////////////////////////////////////////////
/// Default constructor
///
/// \param Code : Response status code (InvalidResponse by default)
/// \param Message : Response message (empty by default)
///
////////////////////////////////////////////////////////////
Response(Status Code = InvalidResponse, const std::string& Message = "");
////////////////////////////////////////////////////////////
/// Convenience function to check if the response status code
/// means a success
///
/// \return True if status is success (code < 400)
///
////////////////////////////////////////////////////////////
bool IsOk() const;
////////////////////////////////////////////////////////////
/// Get the response status code
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Status GetStatus() const;
////////////////////////////////////////////////////////////
/// Get the full message contained in the response
///
/// \return The response message
///
////////////////////////////////////////////////////////////
const std::string& GetMessage() const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Status myStatus; ///< Status code returned from the server
std::string myMessage; ///< Last message received from the server
};
////////////////////////////////////////////////////////////
/// Specialization of FTP response returning a directory
////////////////////////////////////////////////////////////
class SFML_API DirectoryResponse : public Response
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
/// \param Resp : Source response
///
////////////////////////////////////////////////////////////
DirectoryResponse(Response Resp);
////////////////////////////////////////////////////////////
/// Get the directory returned in the response
///
/// \return Directory name
///
////////////////////////////////////////////////////////////
const std::string& GetDirectory() const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::string myDirectory; ///< Directory extracted from the response message
};
////////////////////////////////////////////////////////////
/// Specialization of FTP response returning a filename lisiting
////////////////////////////////////////////////////////////
class SFML_API ListingResponse : public Response
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
/// \param Resp : Source response
/// \param Data : Data containing the raw listing
///
////////////////////////////////////////////////////////////
ListingResponse(Response Resp, const std::vector<char>& Data);
////////////////////////////////////////////////////////////
/// Get the number of filenames in the listing
///
/// \return Total number of filenames
///
////////////////////////////////////////////////////////////
std::size_t GetCount() const;
////////////////////////////////////////////////////////////
/// Get the Index-th filename in the directory
///
/// \param Index : Index of the filename to get
///
/// \return Index-th filename
///
////////////////////////////////////////////////////////////
const std::string& GetFilename(std::size_t Index) const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::vector<std::string> myFilenames; ///< Filenames extracted from the data
};
////////////////////////////////////////////////////////////
/// Destructor -- close the connection with the server
///
////////////////////////////////////////////////////////////
~Ftp();
////////////////////////////////////////////////////////////
/// Connect to the specified FTP server
///
/// \param Server : FTP server to connect to
/// \param Port : Port used for connection (21 by default, standard FTP port)
/// \param Timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Connect(const IPAddress& Server, unsigned short Port = 21, float Timeout = 0.f);
////////////////////////////////////////////////////////////
/// Log in using anonymous account
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Login();
////////////////////////////////////////////////////////////
/// Log in using a username and a password
///
/// \param UserName : User name
/// \param Password : Password
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Login(const std::string& UserName, const std::string& Password);
////////////////////////////////////////////////////////////
/// Close the connection with FTP server
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Disconnect();
////////////////////////////////////////////////////////////
/// Send a null command just to prevent from being disconnected
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response KeepAlive();
////////////////////////////////////////////////////////////
/// Get the current working directory
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
DirectoryResponse GetWorkingDirectory();
////////////////////////////////////////////////////////////
/// Get the contents of the given directory
/// (subdirectories and files)
///
/// \param Directory : Directory to list ("" by default, the current one)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
ListingResponse GetDirectoryListing(const std::string& Directory = "");
////////////////////////////////////////////////////////////
/// Change the current working directory
///
/// \param Directory : New directory, relative to the current one
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response ChangeDirectory(const std::string& Directory);
////////////////////////////////////////////////////////////
/// Go to the parent directory of the current one
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response ParentDirectory();
////////////////////////////////////////////////////////////
/// Create a new directory
///
/// \param Name : Name of the directory to create
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response MakeDirectory(const std::string& Name);
////////////////////////////////////////////////////////////
/// Remove an existing directory
///
/// \param Name : Name of the directory to remove
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response DeleteDirectory(const std::string& Name);
////////////////////////////////////////////////////////////
/// Rename a file
///
/// \param File : File to rename
/// \param NewName : New name
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response RenameFile(const std::string& File, const std::string& NewName);
////////////////////////////////////////////////////////////
/// Remove an existing file
///
/// \param Name : File to remove
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response DeleteFile(const std::string& Name);
////////////////////////////////////////////////////////////
/// Download a file from the server
///
/// \param DistantFile : Path of the distant file to download
/// \param DestPath : Where to put to file on the local computer
/// \param Mode : Transfer mode (binary by default)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode = Binary);
////////////////////////////////////////////////////////////
/// Upload a file to the server
///
/// \param LocalFile : Path of the local file to upload
/// \param DestPath : Where to put to file on the server
/// \param Mode : Transfer mode (binary by default)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode = Binary);
private :
////////////////////////////////////////////////////////////
/// Send a command to the FTP server
///
/// \param Command : Command to send
/// \param Parameter : Command parameter ("" by default)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response SendCommand(const std::string& Command, const std::string& Parameter = "");
////////////////////////////////////////////////////////////
/// Receive a response from the server
/// (usually after a command has been sent)
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response GetResponse();
////////////////////////////////////////////////////////////
/// Utility class for exchanging datas with the server
/// on the data channel
////////////////////////////////////////////////////////////
class DataChannel;
friend class DataChannel;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTCP myCommandSocket; ///< Socket holding the control connection with the server
};
} // namespace sf
#endif // SFML_FTP_HPP

View File

@ -1,340 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_HTTP_HPP
#define SFML_HTTP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <map>
#include <string>
namespace sf
{
////////////////////////////////////////////////////////////
/// This class provides methods for manipulating the HTTP
/// protocol (described in RFC 1945).
/// It can connect to a website, get its files, send requests, etc.
////////////////////////////////////////////////////////////
class SFML_API Http : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// This class wraps an HTTP request, which is basically :
/// - a header with a method, a target URI, and a set of field/value pairs
/// - an optional body (for POST requests)
////////////////////////////////////////////////////////////
class SFML_API Request
{
public :
////////////////////////////////////////////////////////////
/// Enumerate the available HTTP methods for a request
////////////////////////////////////////////////////////////
enum Method
{
Get, ///< Request in get mode, standard method to retrieve a page
Post, ///< Request in post mode, usually to send data to a page
Head ///< Request a page's header only
};
////////////////////////////////////////////////////////////
/// Default constructor
///
/// \param RequestMethod : Method to use for the request (Get by default)
/// \param URI : Target URI ("/" by default -- index page)
/// \param Body : Content of the request's body (empty by default)
///
////////////////////////////////////////////////////////////
Request(Method RequestMethod = Get, const std::string& URI = "/", const std::string& Body = "");
////////////////////////////////////////////////////////////
/// Set the value of a field; the field is added if it doesn't exist
///
/// \param Field : Name of the field to set (case-insensitive)
/// \param Value : Value of the field
///
////////////////////////////////////////////////////////////
void SetField(const std::string& Field, const std::string& Value);
////////////////////////////////////////////////////////////
/// Set the request method.
/// This parameter is Http::Request::Get by default
///
/// \param RequestMethod : Method to use for the request
///
////////////////////////////////////////////////////////////
void SetMethod(Method RequestMethod);
////////////////////////////////////////////////////////////
/// Set the target URI of the request.
/// This parameter is "/" by default
///
/// \param URI : URI to request, local to the host
///
////////////////////////////////////////////////////////////
void SetURI(const std::string& URI);
////////////////////////////////////////////////////////////
/// Set the HTTP version of the request.
/// This parameter is 1.0 by default
///
/// \param Major : Major version number
/// \param Minor : Minor version number
///
////////////////////////////////////////////////////////////
void SetHttpVersion(unsigned int Major, unsigned int Minor);
////////////////////////////////////////////////////////////
/// Set the body of the request. This parameter is optional and
/// makes sense only for POST requests.
/// This parameter is empty by default
///
/// \param Body : Content of the request body
///
////////////////////////////////////////////////////////////
void SetBody(const std::string& Body);
private :
friend class Http;
////////////////////////////////////////////////////////////
/// Get the string representation of the request header
///
/// \return String containing the request
///
////////////////////////////////////////////////////////////
std::string ToString() const;
////////////////////////////////////////////////////////////
/// Check if the given field has been defined
///
/// \param Field : Name of the field to check (case-insensitive)
///
/// \return True if the field exists
///
////////////////////////////////////////////////////////////
bool HasField(const std::string& Field) const;
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<std::string, std::string> FieldTable;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
FieldTable myFields; ///< Fields of the header
Method myMethod; ///< Method to use for the request
std::string myURI; ///< Target URI of the request
unsigned int myMajorVersion; ///< Major HTTP version
unsigned int myMinorVersion; ///< Minor HTTP version
std::string myBody; ///< Body of the request
};
////////////////////////////////////////////////////////////
/// This class wraps an HTTP response, which is basically :
/// - a header with a status code and a set of field/value pairs
/// - a body (the content of the requested resource)
////////////////////////////////////////////////////////////
class SFML_API Response
{
public :
////////////////////////////////////////////////////////////
/// Enumerate all the valid status codes returned in
/// a HTTP response
////////////////////////////////////////////////////////////
enum Status
{
// 2xx: success
Ok = 200, ///< Most common code returned when operation was successful
Created = 201, ///< The resource has successfully been created
Accepted = 202, ///< The request has been accepted, but will be processed later by the server
NoContent = 204, ///< Sent when the server didn't send any data in return
// 3xx: redirection
MultipleChoices = 300, ///< The requested page can be accessed from several locations
MovedPermanently = 301, ///< The requested page has permanently moved to a new location
MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
// 4xx: client error
BadRequest = 400, ///< The server couldn't understand the request (syntax error)
Unauthorized = 401, ///< The requested page needs an authentification to be accessed
Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
NotFound = 404, ///< The requested page doesn't exist
// 5xx: server error
InternalServerError = 500, ///< The server encountered an unexpected error
NotImplemented = 501, ///< The server doesn't implement a requested feature
BadGateway = 502, ///< The gateway server has received an error from the source server
ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
// 10xx: SFML custom codes
InvalidResponse = 1000, ///< Response is not a valid HTTP one
ConnectionFailed = 1001 ///< Connection with server failed
};
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Response();
////////////////////////////////////////////////////////////
/// Get the value of a field
///
/// \param Field : Name of the field to get (case-insensitive)
///
/// \return Value of the field, or empty string if not found
///
////////////////////////////////////////////////////////////
const std::string& GetField(const std::string& Field) const;
////////////////////////////////////////////////////////////
/// Get the header's status code
///
/// \return Header's status code
///
////////////////////////////////////////////////////////////
Status GetStatus() const;
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
///
/// \return Major version number
///
////////////////////////////////////////////////////////////
unsigned int GetMajorHttpVersion() const;
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
///
/// \return Major version number
///
////////////////////////////////////////////////////////////
unsigned int GetMinorHttpVersion() const;
////////////////////////////////////////////////////////////
/// Get the body of the response. The body can contain :
/// - the requested page (for GET requests)
/// - a response from the server (for POST requests)
/// - nothing (for HEAD requests)
/// - an error message (in case of an error)
///
/// \return The response body
///
////////////////////////////////////////////////////////////
const std::string& GetBody() const;
private :
friend class Http;
////////////////////////////////////////////////////////////
/// Construct the header from a response string
///
/// \param Data : Content of the response's header to parse
///
////////////////////////////////////////////////////////////
void FromString(const std::string& Data);
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<std::string, std::string> FieldTable;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
FieldTable myFields; ///< Fields of the header
Status myStatus; ///< Status code
unsigned int myMajorVersion; ///< Major HTTP version
unsigned int myMinorVersion; ///< Minor HTTP version
std::string myBody; ///< Body of the response
};
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Http();
////////////////////////////////////////////////////////////
/// Construct the Http instance with the target host
///
/// \param Host : Web server to connect to
/// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
///
////////////////////////////////////////////////////////////
Http(const std::string& Host, unsigned short Port = 0);
////////////////////////////////////////////////////////////
/// Set the target host
///
/// \param Host : Web server to connect to
/// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
///
////////////////////////////////////////////////////////////
void SetHost(const std::string& Host, unsigned short Port = 0);
////////////////////////////////////////////////////////////
/// Send a HTTP request and return the server's response.
/// You must be connected to a host before sending requests.
/// Any missing mandatory header field will be added with an appropriate value.
/// Warning : this function waits for the server's response and may
/// not return instantly; use a thread if you don't want to block your
/// application.
///
/// \param Req : Request to send
/// \param Timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
///
/// \return Server's response
///
////////////////////////////////////////////////////////////
Response SendRequest(const Request& Req, float Timeout = 0.f);
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTCP myConnection; ///< Connection to the host
IPAddress myHost; ///< Web host address
std::string myHostName; ///< Web host name
unsigned short myPort; ///< Port used for connection with host
};
} // namespace sf
#endif // SFML_HTTP_HPP

View File

@ -1,231 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_IPADDRESS_HPP
#define SFML_IPADDRESS_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <istream>
#include <ostream>
#include <string>
namespace sf
{
////////////////////////////////////////////////////////////
/// IPAddress provides easy manipulation of IP v4 addresses
////////////////////////////////////////////////////////////
class SFML_API IPAddress
{
public :
////////////////////////////////////////////////////////////
/// Default constructor -- constructs an invalid address
///
////////////////////////////////////////////////////////////
IPAddress();
////////////////////////////////////////////////////////////
/// Construct the address from a string
///
/// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
///
////////////////////////////////////////////////////////////
IPAddress(const std::string& Address);
////////////////////////////////////////////////////////////
/// Construct the address from a C-style string ;
/// Needed for implicit conversions from literal strings to IPAddress to work
///
/// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
///
////////////////////////////////////////////////////////////
IPAddress(const char* Address);
////////////////////////////////////////////////////////////
/// Construct the address from 4 bytes
///
/// \param Byte0 : First byte of the address
/// \param Byte1 : Second byte of the address
/// \param Byte2 : Third byte of the address
/// \param Byte3 : Fourth byte of the address
///
////////////////////////////////////////////////////////////
IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3);
////////////////////////////////////////////////////////////
/// Construct the address from a 32-bits integer
///
/// \param Address : 4 bytes of the address packed into a 32-bits integer
///
////////////////////////////////////////////////////////////
IPAddress(Uint32 Address);
////////////////////////////////////////////////////////////
/// Tell if the address is a valid one
///
/// \return True if address has a valid syntax
///
////////////////////////////////////////////////////////////
bool IsValid() const;
////////////////////////////////////////////////////////////
/// Get a string representation of the address
///
/// \return String representation of the IP address ("xxx.xxx.xxx.xxx")
///
////////////////////////////////////////////////////////////
std::string ToString() const;
////////////////////////////////////////////////////////////
/// Get an integer representation of the address
///
/// \return 32-bits integer containing the 4 bytes of the address, in system endianness
///
////////////////////////////////////////////////////////////
Uint32 ToInteger() const;
////////////////////////////////////////////////////////////
/// Get the computer's local IP address (from the LAN point of view)
///
/// \return Local IP address
///
////////////////////////////////////////////////////////////
static IPAddress GetLocalAddress();
////////////////////////////////////////////////////////////
/// Get the computer's public IP address (from the web point of view).
/// The only way to get a public address is to ask it to a
/// distant website ; as a consequence, this function may be
/// very slow -- use it as few as possible !
///
/// \param Timeout : Maximum time to wait, in seconds (0 by default : no timeout)
///
/// \return Public IP address
///
////////////////////////////////////////////////////////////
static IPAddress GetPublicAddress(float Timeout = 0.f);
////////////////////////////////////////////////////////////
/// Comparison operator ==
///
/// \param Other : Address to compare
///
/// \return True if *this == Other
///
////////////////////////////////////////////////////////////
bool operator ==(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator !=
///
/// \param Other : Address to compare
///
/// \return True if *this != Other
///
////////////////////////////////////////////////////////////
bool operator !=(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <
///
/// \param Other : Address to compare
///
/// \return True if *this < Other
///
////////////////////////////////////////////////////////////
bool operator <(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator >
///
/// \param Other : Address to compare
///
/// \return True if *this > Other
///
////////////////////////////////////////////////////////////
bool operator >(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <=
///
/// \param Other : Address to compare
///
/// \return True if *this <= Other
///
////////////////////////////////////////////////////////////
bool operator <=(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator >=
///
/// \param Other : Address to compare
///
/// \return True if *this >= Other
///
////////////////////////////////////////////////////////////
bool operator >=(const IPAddress& Other) const;
////////////////////////////////////////////////////////////
// Static member data
////////////////////////////////////////////////////////////
static const IPAddress LocalHost; ///< Local host address (to connect to the same computer)
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Uint32 myAddress; ///< Address stored as an unsigned 32 bits integer
};
////////////////////////////////////////////////////////////
/// Operator >> overload to extract an address from an input stream
///
/// \param Stream : Input stream
/// \param Address : Address to extract
///
/// \return Reference to the input stream
///
////////////////////////////////////////////////////////////
SFML_API std::istream& operator >>(std::istream& Stream, IPAddress& Address);
////////////////////////////////////////////////////////////
/// Operator << overload to print an address to an output stream
///
/// \param Stream : Output stream
/// \param Address : Address to print
///
/// \return Reference to the output stream
///
////////////////////////////////////////////////////////////
SFML_API std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address);
} // namespace sf
#endif // SFML_IPADDRESS_HPP

View File

@ -1,187 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_PACKET_HPP
#define SFML_PACKET_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <string>
#include <vector>
namespace sf
{
////////////////////////////////////////////////////////////
/// Packet wraps data to send / to receive through the network
////////////////////////////////////////////////////////////
class SFML_API Packet
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Packet();
////////////////////////////////////////////////////////////
/// Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Packet();
////////////////////////////////////////////////////////////
/// Append data to the end of the packet
///
/// \param Data : Pointer to the bytes to append
/// \param SizeInBytes : Number of bytes to append
///
////////////////////////////////////////////////////////////
void Append(const void* Data, std::size_t SizeInBytes);
////////////////////////////////////////////////////////////
/// Clear the packet data
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Get a pointer to the data contained in the packet
/// Warning : the returned pointer may be invalid after you
/// append data to the packet
///
/// \return Pointer to the data
///
////////////////////////////////////////////////////////////
const char* GetData() const;
////////////////////////////////////////////////////////////
/// Get the size of the data contained in the packet
///
/// \return Data size, in bytes
///
////////////////////////////////////////////////////////////
std::size_t GetDataSize() const;
////////////////////////////////////////////////////////////
/// Tell if the reading position has reached the end of the packet
///
/// \return True if all data have been read into the packet
///
////////////////////////////////////////////////////////////
bool EndOfPacket() const;
////////////////////////////////////////////////////////////
/// Return the validity of packet
///
/// \return True if last data extraction from packet was successful
///
////////////////////////////////////////////////////////////
operator bool() const;
////////////////////////////////////////////////////////////
/// Operator >> overloads to extract data from the packet
///
////////////////////////////////////////////////////////////
Packet& operator >>(bool& Data);
Packet& operator >>(Int8& Data);
Packet& operator >>(Uint8& Data);
Packet& operator >>(Int16& Data);
Packet& operator >>(Uint16& Data);
Packet& operator >>(Int32& Data);
Packet& operator >>(Uint32& Data);
Packet& operator >>(float& Data);
Packet& operator >>(double& Data);
Packet& operator >>(char* Data);
Packet& operator >>(std::string& Data);
Packet& operator >>(wchar_t* Data);
Packet& operator >>(std::wstring& Data);
////////////////////////////////////////////////////////////
/// Operator << overloads to put data into the packet
///
////////////////////////////////////////////////////////////
Packet& operator <<(bool Data);
Packet& operator <<(Int8 Data);
Packet& operator <<(Uint8 Data);
Packet& operator <<(Int16 Data);
Packet& operator <<(Uint16 Data);
Packet& operator <<(Int32 Data);
Packet& operator <<(Uint32 Data);
Packet& operator <<(float Data);
Packet& operator <<(double Data);
Packet& operator <<(const char* Data);
Packet& operator <<(const std::string& Data);
Packet& operator <<(const wchar_t* Data);
Packet& operator <<(const std::wstring& Data);
private :
friend class SocketTCP;
friend class SocketUDP;
////////////////////////////////////////////////////////////
/// Check if the packet can extract a given size of bytes
///
/// \param Size : Size to check
///
/// \return True if Size bytes can be read from the packet's data
///
////////////////////////////////////////////////////////////
bool CheckSize(std::size_t Size);
////////////////////////////////////////////////////////////
/// Called before the packet is sent to the network
///
/// \param DataSize : Variable to fill with the size of data to send
///
/// \return Pointer to the array of bytes to send
///
////////////////////////////////////////////////////////////
virtual const char* OnSend(std::size_t& DataSize);
////////////////////////////////////////////////////////////
/// Called after the packet has been received from the network
///
/// \param Data : Pointer to the array of received bytes
/// \param DataSize : Size of the array of bytes
///
////////////////////////////////////////////////////////////
virtual void OnReceive(const char* Data, std::size_t DataSize);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
std::vector<char> myData; ///< Data stored in the packet
std::size_t myReadPos; ///< Current reading position in the packet
bool myIsValid; ///< Reading state of the packet
};
} // namespace sf
#endif // SFML_PACKET_HPP

View File

@ -1,116 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SELECTOR_HPP
#define SFML_SELECTOR_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketUDP.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/SelectorBase.hpp>
#include <map>
namespace sf
{
////////////////////////////////////////////////////////////
/// Selector allow reading from multiple sockets
/// without blocking. It's a kind of multiplexer
////////////////////////////////////////////////////////////
template <typename Type>
class Selector : private SelectorBase
{
public :
////////////////////////////////////////////////////////////
/// Add a socket to watch
///
/// \param Socket : Socket to add
///
////////////////////////////////////////////////////////////
void Add(Type Socket);
////////////////////////////////////////////////////////////
/// Remove a socket
///
/// \param Socket : Socket to remove
///
////////////////////////////////////////////////////////////
void Remove(Type Socket);
////////////////////////////////////////////////////////////
/// Remove all sockets
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
///
/// \param Timeout : Timeout, in seconds (0 by default : no timeout)
///
/// \return Number of sockets ready to be read
///
////////////////////////////////////////////////////////////
unsigned int Wait(float Timeout = 0.f);
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
///
/// \param Index : Index of the socket to get
///
/// \return The Index-th socket
///
////////////////////////////////////////////////////////////
Type GetSocketReady(unsigned int Index);
private :
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<SocketHelper::SocketType, Type> SocketTable;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTable mySockets; ///< Table matching the SFML socket instances with their low-level handles
};
#include <SFML/Network/Selector.inl>
// Let's define the two only valid types of Selector
typedef Selector<SocketUDP> SelectorUDP;
typedef Selector<SocketTCP> SelectorTCP;
} // namespace sf
#endif // SFML_SELECTOR_HPP

View File

@ -1,97 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Add a socket to watch
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Add(Type Socket)
{
if (Socket.IsValid())
{
SelectorBase::Add(Socket.mySocket);
mySockets[Socket.mySocket] = Socket;
}
}
////////////////////////////////////////////////////////////
/// Remove a socket
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Remove(Type Socket)
{
typename SocketTable::iterator It = mySockets.find(Socket.mySocket);
if (It != mySockets.end())
{
SelectorBase::Remove(Socket.mySocket);
mySockets.erase(It);
}
}
////////////////////////////////////////////////////////////
/// Remove all sockets
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Clear()
{
SelectorBase::Clear();
mySockets.clear();
}
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
////////////////////////////////////////////////////////////
template <typename Type>
unsigned int Selector<Type>::Wait(float Timeout)
{
// No socket in the selector : return 0
if (mySockets.empty())
return 0;
return SelectorBase::Wait(Timeout);
}
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
////////////////////////////////////////////////////////////
template <typename Type>
Type Selector<Type>::GetSocketReady(unsigned int Index)
{
SocketHelper::SocketType Socket = SelectorBase::GetSocketReady(Index);
typename SocketTable::const_iterator It = mySockets.find(Socket);
if (It != mySockets.end())
return It->second;
else
return Type(Socket);
}

View File

@ -1,112 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SELECTORBASE_HPP
#define SFML_SELECTORBASE_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/Network/SocketHelper.hpp>
#include <map>
namespace sf
{
////////////////////////////////////////////////////////////
/// Private base class for selectors.
/// As Selector is a template class, this base is needed so that
/// every system call get compiled in SFML (not inlined)
////////////////////////////////////////////////////////////
class SFML_API SelectorBase
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SelectorBase();
////////////////////////////////////////////////////////////
/// Add a socket to watch
///
/// \param Socket : Socket to add
///
////////////////////////////////////////////////////////////
void Add(SocketHelper::SocketType Socket);
////////////////////////////////////////////////////////////
/// Remove a socket
///
/// \param Socket : Socket to remove
///
////////////////////////////////////////////////////////////
void Remove(SocketHelper::SocketType Socket);
////////////////////////////////////////////////////////////
/// Remove all sockets
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
///
/// \param Timeout : Timeout, in seconds (0 by default : no timeout)
///
/// \return Number of sockets ready to be read
///
////////////////////////////////////////////////////////////
unsigned int Wait(float Timeout = 0.f);
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
///
/// \param Index : Index of the socket to get
///
/// \return The Index-th socket
///
////////////////////////////////////////////////////////////
SocketHelper::SocketType GetSocketReady(unsigned int Index);
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
fd_set mySet; ///< Set of socket to watch
fd_set mySetReady; ///< Set of socket which are ready for reading
int myMaxSocket; ///< Maximum socket index
};
} // namespace sf
#endif // SFML_SELECTORBASE_HPP

View File

@ -1,64 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPER_HPP
#define SFML_SOCKETHELPER_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
namespace sf
{
namespace Socket
{
////////////////////////////////////////////////////////////
/// Enumeration of status returned by socket functions
////////////////////////////////////////////////////////////
enum Status
{
Done, ///< The socket has sent / received the data
NotReady, ///< The socket is not ready to send / receive data yet
Disconnected, ///< The TCP socket has been disconnected
Error ///< An unexpected error happened
};
}
} // namespace sf
#ifdef SFML_SYSTEM_WINDOWS
#include <SFML/Network/Win32/SocketHelper.hpp>
#else
#include <SFML/Network/Unix/SocketHelper.hpp>
#endif
#endif // SFML_SOCKETHELPER_HPP

View File

@ -1,225 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETTCP_HPP
#define SFML_SOCKETTCP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
#include <vector>
namespace sf
{
class Packet;
class IPAddress;
template <typename> class Selector;
////////////////////////////////////////////////////////////
/// SocketTCP wraps a socket using TCP protocol to
/// send data safely (but a bit slower)
////////////////////////////////////////////////////////////
class SFML_API SocketTCP
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SocketTCP();
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket.
/// The default behaviour of a socket is blocking
///
/// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
///
////////////////////////////////////////////////////////////
void SetBlocking(bool Blocking);
////////////////////////////////////////////////////////////
/// Connect to another computer on a specified port
///
/// \param Port : Port to use for transfers (warning : ports < 1024 are reserved)
/// \param HostAddress : IP Address of the host to connect to
/// \param Timeout : Maximum time to wait, in seconds (0 by default : no timeout) (this parameter is ignored for non-blocking sockets)
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
Socket::Status Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout = 0.f);
////////////////////////////////////////////////////////////
/// Listen to a specified port for incoming data or connections
///
/// \param Port : Port to listen to
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Listen(unsigned short Port);
////////////////////////////////////////////////////////////
/// Wait for a connection (must be listening to a port).
/// This function will block if the socket is blocking
///
/// \param Connected : Socket containing the connection with the connected client
/// \param Address : Pointer to an address to fill with client infos (NULL by default)
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Accept(SocketTCP& Connected, IPAddress* Address = NULL);
////////////////////////////////////////////////////////////
/// Send an array of bytes to the host (must be connected first)
///
/// \param Data : Pointer to the bytes to send
/// \param Size : Number of bytes to send
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(const char* Data, std::size_t Size);
////////////////////////////////////////////////////////////
/// Receive an array of bytes from the host (must be connected first).
/// This function will block if the socket is blocking
///
/// \param Data : Pointer to a byte array to fill (make sure it is big enough)
/// \param MaxSize : Maximum number of bytes to read
/// \param SizeReceived : Number of bytes received
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived);
////////////////////////////////////////////////////////////
/// Send a packet of data to the host (must be connected first)
///
/// \param PacketToSend : Packet to send
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(Packet& PacketToSend);
////////////////////////////////////////////////////////////
/// Receive a packet from the host (must be connected first).
/// This function will block if the socket is blocking
///
/// \param PacketToReceive : Packet to fill with received data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(Packet& PacketToReceive);
////////////////////////////////////////////////////////////
/// Close the socket
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Close();
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
///
/// \return True if the socket is valid
///
////////////////////////////////////////////////////////////
bool IsValid() const;
////////////////////////////////////////////////////////////
/// Comparison operator ==
///
/// \param Other : Socket to compare
///
/// \return True if *this == Other
///
////////////////////////////////////////////////////////////
bool operator ==(const SocketTCP& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator !=
///
/// \param Other : Socket to compare
///
/// \return True if *this != Other
///
////////////////////////////////////////////////////////////
bool operator !=(const SocketTCP& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
///
/// \param Other : Socket to compare
///
/// \return True if *this < Other
///
////////////////////////////////////////////////////////////
bool operator <(const SocketTCP& Other) const;
private :
friend class Selector<SocketTCP>;
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
///
/// \param Descriptor : Socket descriptor
///
////////////////////////////////////////////////////////////
SocketTCP(SocketHelper::SocketType Descriptor);
////////////////////////////////////////////////////////////
/// Create the socket
///
/// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
///
////////////////////////////////////////////////////////////
void Create(SocketHelper::SocketType Descriptor = 0);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketHelper::SocketType mySocket; ///< Socket descriptor
std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
};
} // namespace sf
#endif // SFML_SOCKETTCP_HPP

View File

@ -1,226 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETUDP_HPP
#define SFML_SOCKETUDP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
#include <vector>
namespace sf
{
class Packet;
class IPAddress;
template <typename> class Selector;
////////////////////////////////////////////////////////////
/// SocketUDP wraps a socket using UDP protocol to
/// send data fastly (but with less safety)
////////////////////////////////////////////////////////////
class SFML_API SocketUDP
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SocketUDP();
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket.
/// The default behaviour of a socket is blocking
///
/// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
///
////////////////////////////////////////////////////////////
void SetBlocking(bool Blocking);
////////////////////////////////////////////////////////////
/// Bind the socket to a specific port
///
/// \param Port : Port to bind the socket to
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Bind(unsigned short Port);
////////////////////////////////////////////////////////////
/// Unbind the socket from its previous port, if any
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Unbind();
////////////////////////////////////////////////////////////
/// Send an array of bytes
///
/// \param Data : Pointer to the bytes to send
/// \param Size : Number of bytes to send
/// \param Address : Address of the computer to send the packet to
/// \param Port : Port to send the data to
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port);
////////////////////////////////////////////////////////////
/// Receive an array of bytes.
/// This function will block if the socket is blocking
///
/// \param Data : Pointer to a byte array to fill (make sure it is big enough)
/// \param MaxSize : Maximum number of bytes to read
/// \param SizeReceived : Number of bytes received
/// \param Address : Address of the computer which sent the data
/// \param Port : Port on which the remote computer sent the data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address, unsigned short& Port);
////////////////////////////////////////////////////////////
/// Send a packet of data
///
/// \param PacketToSend : Packet to send
/// \param Address : Address of the computer to send the packet to
/// \param Port : Port to send the data to
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port);
////////////////////////////////////////////////////////////
/// Receive a packet.
/// This function will block if the socket is blocking
///
/// \param PacketToReceive : Packet to fill with received data
/// \param Address : Address of the computer which sent the packet
/// \param Port : Port on which the remote computer sent the data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(Packet& PacketToReceive, IPAddress& Address, unsigned short& Port);
////////////////////////////////////////////////////////////
/// Close the socket
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Close();
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
///
/// \return True if the socket is valid
///
////////////////////////////////////////////////////////////
bool IsValid() const;
////////////////////////////////////////////////////////////
/// Get the port the socket is currently bound to
///
/// \return Current port (0 means the socket is not bound)
///
////////////////////////////////////////////////////////////
unsigned short GetPort() const;
////////////////////////////////////////////////////////////
/// Comparison operator ==
///
/// \param Other : Socket to compare
///
/// \return True if *this == Other
///
////////////////////////////////////////////////////////////
bool operator ==(const SocketUDP& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator !=
///
/// \param Other : Socket to compare
///
/// \return True if *this != Other
///
////////////////////////////////////////////////////////////
bool operator !=(const SocketUDP& Other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
///
/// \param Other : Socket to compare
///
/// \return True if *this < Other
///
////////////////////////////////////////////////////////////
bool operator <(const SocketUDP& Other) const;
private :
friend class Selector<SocketUDP>;
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
///
/// \param Descriptor : Socket descriptor
///
////////////////////////////////////////////////////////////
SocketUDP(SocketHelper::SocketType Descriptor);
////////////////////////////////////////////////////////////
/// Create the socket
///
/// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
///
////////////////////////////////////////////////////////////
void Create(SocketHelper::SocketType Descriptor = 0);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketHelper::SocketType mySocket; ///< Socket identifier
unsigned short myPort; ///< Port to which the socket is bound
std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
};
} // namespace sf
#endif // SFML_SOCKETUDP_HPP

View File

@ -1,45 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETS_HPP
#define SFML_SOCKETS_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#ifdef SFML_SYSTEM_WINDOWS
#include <SFML/Network/Win32/Sockets.hpp>
#else
#include <SFML/Network/Unix/Sockets.hpp>
#endif
#endif // SFML_SOCKETS_HPP

View File

@ -1,96 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPERUNIX_HPP
#define SFML_SOCKETHELPERUNIX_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// This class defines helper functions to do all the
/// non-portable socket stuff. This class is meant for internal
/// use only
////////////////////////////////////////////////////////////
class SFML_API SocketHelper
{
public :
////////////////////////////////////////////////////////////
// Define some socket types
////////////////////////////////////////////////////////////
typedef int SocketType;
typedef socklen_t LengthType;
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
///
/// \return Unique value of the invalid socket
///
////////////////////////////////////////////////////////////
static SocketType InvalidSocket();
////////////////////////////////////////////////////////////
/// Close / destroy a socket
///
/// \param Socket : Socket to close
///
/// \return True on success
///
////////////////////////////////////////////////////////////
static bool Close(SocketType Socket);
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
///
/// \param Socket : Socket to modify
/// \param Block : New blocking state of the socket
///
////////////////////////////////////////////////////////////
static void SetBlocking(SocketType Socket, bool Block);
////////////////////////////////////////////////////////////
/// Get the last socket error status
///
/// \return Status corresponding to the last socket error
///
////////////////////////////////////////////////////////////
static Socket::Status GetErrorStatus();
};
} // namespace sf
#endif // SFML_SOCKETHELPERUNIX_HPP

View File

@ -1,90 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPERWIN32_HPP
#define SFML_SOCKETHELPERWIN32_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <winsock2.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// This class defines helper functions to do all the
/// non-portable socket stuff. This class is meant for internal
/// use only
////////////////////////////////////////////////////////////
class SFML_API SocketHelper
{
public :
////////////////////////////////////////////////////////////
// Define some socket types
////////////////////////////////////////////////////////////
typedef SOCKET SocketType;
typedef int LengthType;
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
///
/// \return Unique value of the invalid socket
///
////////////////////////////////////////////////////////////
static SocketType InvalidSocket();
////////////////////////////////////////////////////////////
/// Close / destroy a socket
///
/// \param Socket : Socket to close
///
/// \return True on success
///
////////////////////////////////////////////////////////////
static bool Close(SocketType Socket);
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
///
/// \param Socket : Socket to modify
/// \param Block : New blocking state of the socket
///
////////////////////////////////////////////////////////////
static void SetBlocking(SocketType Socket, bool Block);
////////////////////////////////////////////////////////////
/// Get the last socket error status
///
/// \return Status corresponding to the last socket error
///
////////////////////////////////////////////////////////////
static Socket::Status GetErrorStatus();
};
} // namespace sf
#endif // SFML_SOCKETHELPERWIN32_HPP

View File

@ -1,43 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SYSTEM_HPP
#define SFML_SYSTEM_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
// #include <SFML/System/Clock.hpp>
// #include <SFML/System/Lock.hpp>
// #include <SFML/System/Mutex.hpp>
// #include <SFML/System/Randomizer.hpp>
// #include <SFML/System/Sleep.hpp>
// #include <SFML/System/Thread.hpp>
// #include <SFML/System/Unicode.hpp>
// #include <SFML/System/Vector2.hpp>
// #include <SFML/System/Vector3.hpp>
#endif // SFML_SYSTEM_HPP

View File

@ -1,70 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_NONCOPYABLE_HPP
#define SFML_NONCOPYABLE_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
namespace sf
{
////////////////////////////////////////////////////////////
/// Utility base class to easily declare non-copyable classes.
/// Just inherit from NonCopyable to get a non-copyable class
////////////////////////////////////////////////////////////
struct SFML_API NonCopyable
{
protected :
////////////////////////////////////////////////////////////
/// The default constructor won't be generated, so provide it
///
////////////////////////////////////////////////////////////
NonCopyable() {}
private :
////////////////////////////////////////////////////////////
/// Copy constructor : declare it private and don't implement
/// it to prevent from calling it
///
////////////////////////////////////////////////////////////
NonCopyable(const NonCopyable&);
////////////////////////////////////////////////////////////
/// Assignment operator : declare it private and don't implement
/// it to prevent from calling it
///
////////////////////////////////////////////////////////////
NonCopyable& operator =(const NonCopyable&);
};
} // namespace sf
#endif // SFML_NONCOPYABLE_HPP

View File

@ -1,709 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Ftp.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <sstream>
namespace sf
{
////////////////////////////////////////////////////////////
// Utility class for exchanging stuff with the server
// on the data channel
////////////////////////////////////////////////////////////
class Ftp::DataChannel : NonCopyable
{
public :
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
DataChannel(Ftp& Owner);
////////////////////////////////////////////////////////////
// Destructor
////////////////////////////////////////////////////////////
~DataChannel();
////////////////////////////////////////////////////////////
// Open the data channel using the specified mode and port
////////////////////////////////////////////////////////////
Ftp::Response Open(Ftp::TransferMode Mode);
////////////////////////////////////////////////////////////
// Send data on the data channel
////////////////////////////////////////////////////////////
void Send(const std::vector<char>& Data);
////////////////////////////////////////////////////////////
// Receive data on the data channel until it is closed
////////////////////////////////////////////////////////////
void Receive(std::vector<char>& Data);
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Ftp& myFtp; ///< Reference to the owner Ftp instance
SocketTCP myDataSocket; ///< Socket used for data transfers
};
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Ftp::Response::Response(Status Code, const std::string& Message) :
myStatus (Code),
myMessage(Message)
{
}
////////////////////////////////////////////////////////////
/// Convenience function to check if the response status code
/// means a success
////////////////////////////////////////////////////////////
bool Ftp::Response::IsOk() const
{
return myStatus < 400;
}
////////////////////////////////////////////////////////////
/// Get the response status code
////////////////////////////////////////////////////////////
Ftp::Response::Status Ftp::Response::GetStatus() const
{
return myStatus;
}
////////////////////////////////////////////////////////////
/// Get the full message contained in the response
////////////////////////////////////////////////////////////
const std::string& Ftp::Response::GetMessage() const
{
return myMessage;
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Ftp::DirectoryResponse::DirectoryResponse(Ftp::Response Resp) :
Ftp::Response(Resp)
{
if (IsOk())
{
// Extract the directory from the server response
std::string::size_type Begin = Resp.GetMessage().find('"', 0);
std::string::size_type End = Resp.GetMessage().find('"', Begin + 1);
myDirectory = Resp.GetMessage().substr(Begin + 1, End - Begin - 1);
}
}
////////////////////////////////////////////////////////////
/// Get the directory returned in the response
////////////////////////////////////////////////////////////
const std::string& Ftp::DirectoryResponse::GetDirectory() const
{
return myDirectory;
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Ftp::ListingResponse::ListingResponse(Ftp::Response Resp, const std::vector<char>& Data) :
Ftp::Response(Resp)
{
if (IsOk())
{
// Fill the array of strings
std::string Paths(Data.begin(), Data.end());
std::string::size_type LastPos = 0;
for (std::string::size_type Pos = Paths.find("\r\n"); Pos != std::string::npos; Pos = Paths.find("\r\n", LastPos))
{
myFilenames.push_back(Paths.substr(LastPos, Pos - LastPos));
LastPos = Pos + 2;
}
}
}
////////////////////////////////////////////////////////////
/// Get the number of filenames in the listing
////////////////////////////////////////////////////////////
std::size_t Ftp::ListingResponse::GetCount() const
{
return myFilenames.size();
}
////////////////////////////////////////////////////////////
/// Get the Index-th filename in the directory
////////////////////////////////////////////////////////////
const std::string& Ftp::ListingResponse::GetFilename(std::size_t Index) const
{
return myFilenames[Index];
}
////////////////////////////////////////////////////////////
/// Destructor -- close the connection with the server
////////////////////////////////////////////////////////////
Ftp::~Ftp()
{
Disconnect();
}
////////////////////////////////////////////////////////////
/// Connect to the specified FTP server
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Connect(const IPAddress& Server, unsigned short Port, float Timeout)
{
// Connect to the server
if (myCommandSocket.Connect(Port, Server, Timeout) != Socket::Done)
return Response(Response::ConnectionFailed);
// Get the response to the connection
return GetResponse();
}
////////////////////////////////////////////////////////////
/// Log in using anonymous account
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Login()
{
return Login("anonymous", "user@sfml-dev.org");
}
////////////////////////////////////////////////////////////
/// Log in using a username and a password
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Login(const std::string& UserName, const std::string& Password)
{
Response Resp = SendCommand("USER", UserName);
if (Resp.IsOk())
Resp = SendCommand("PASS", Password);
return Resp;
}
////////////////////////////////////////////////////////////
/// Close the connection with FTP server
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Disconnect()
{
// Send the exit command
Response Resp = SendCommand("QUIT");
if (Resp.IsOk())
myCommandSocket.Close();
return Resp;
}
////////////////////////////////////////////////////////////
/// Send a null command just to prevent from being disconnected
////////////////////////////////////////////////////////////
Ftp::Response Ftp::KeepAlive()
{
return SendCommand("NOOP");
}
////////////////////////////////////////////////////////////
/// Get the current working directory
////////////////////////////////////////////////////////////
Ftp::DirectoryResponse Ftp::GetWorkingDirectory()
{
return DirectoryResponse(SendCommand("PWD"));
}
////////////////////////////////////////////////////////////
/// Get the contents of the given directory
/// (subdirectories and files)
////////////////////////////////////////////////////////////
Ftp::ListingResponse Ftp::GetDirectoryListing(const std::string& Directory)
{
// Open a data channel on default port (20) using ASCII transfer mode
std::vector<char> DirData;
DataChannel Data(*this);
Response Resp = Data.Open(Ascii);
if (Resp.IsOk())
{
// Tell the server to send us the listing
Resp = SendCommand("NLST", Directory);
if (Resp.IsOk())
{
// Receive the listing
Data.Receive(DirData);
// Get the response from the server
Resp = GetResponse();
}
}
return ListingResponse(Resp, DirData);
}
////////////////////////////////////////////////////////////
/// Change the current working directory
////////////////////////////////////////////////////////////
Ftp::Response Ftp::ChangeDirectory(const std::string& Directory)
{
return SendCommand("CWD", Directory);
}
////////////////////////////////////////////////////////////
/// Go to the parent directory of the current one
////////////////////////////////////////////////////////////
Ftp::Response Ftp::ParentDirectory()
{
return SendCommand("CDUP");
}
////////////////////////////////////////////////////////////
/// Create a new directory
////////////////////////////////////////////////////////////
Ftp::Response Ftp::MakeDirectory(const std::string& Name)
{
return SendCommand("MKD", Name);
}
////////////////////////////////////////////////////////////
/// Remove an existing directory
////////////////////////////////////////////////////////////
Ftp::Response Ftp::DeleteDirectory(const std::string& Name)
{
return SendCommand("RMD", Name);
}
////////////////////////////////////////////////////////////
/// Rename a file
////////////////////////////////////////////////////////////
Ftp::Response Ftp::RenameFile(const std::string& File, const std::string& NewName)
{
Response Resp = SendCommand("RNFR", File);
if (Resp.IsOk())
Resp = SendCommand("RNTO", NewName);
return Resp;
}
////////////////////////////////////////////////////////////
/// Remove an existing file
////////////////////////////////////////////////////////////
Ftp::Response Ftp::DeleteFile(const std::string& Name)
{
return SendCommand("DELE", Name);
}
////////////////////////////////////////////////////////////
/// Download a file from the server
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode)
{
// Open a data channel using the given transfer mode
DataChannel Data(*this);
Response Resp = Data.Open(Mode);
if (Resp.IsOk())
{
// Tell the server to start the transfer
Resp = SendCommand("RETR", DistantFile);
if (Resp.IsOk())
{
// Receive the file data
std::vector<char> FileData;
Data.Receive(FileData);
// Get the response from the server
Resp = GetResponse();
if (Resp.IsOk())
{
// Extract the filename from the file path
std::string Filename = DistantFile;
std::string::size_type Pos = Filename.find_last_of("/\\");
if (Pos != std::string::npos)
Filename = Filename.substr(Pos + 1);
// Make sure the destination path ends with a slash
std::string Path = DestPath;
if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/'))
Path += "/";
// Create the file and copy the received data into it
std::ofstream File((Path + Filename).c_str(), std::ios_base::binary);
if (!File)
return Response(Response::InvalidFile);
File.write(&FileData[0], static_cast<std::streamsize>(FileData.size()));
}
}
}
return Resp;
}
////////////////////////////////////////////////////////////
/// Upload a file to the server
////////////////////////////////////////////////////////////
Ftp::Response Ftp::Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode)
{
// Get the contents of the file to send
std::ifstream File(LocalFile.c_str(), std::ios_base::binary);
if (!File)
return Response(Response::InvalidFile);
File.seekg(0, std::ios::end);
std::size_t Length = File.tellg();
File.seekg(0, std::ios::beg);
std::vector<char> FileData(Length);
File.read(&FileData[0], static_cast<std::streamsize>(Length));
// Extract the filename from the file path
std::string Filename = LocalFile;
std::string::size_type Pos = Filename.find_last_of("/\\");
if (Pos != std::string::npos)
Filename = Filename.substr(Pos + 1);
// Make sure the destination path ends with a slash
std::string Path = DestPath;
if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/'))
Path += "/";
// Open a data channel using the given transfer mode
DataChannel Data(*this);
Response Resp = Data.Open(Mode);
if (Resp.IsOk())
{
// Tell the server to start the transfer
Resp = SendCommand("STOR", Path + Filename);
if (Resp.IsOk())
{
// Send the file data
Data.Send(FileData);
// Get the response from the server
Resp = GetResponse();
}
}
return Resp;
}
////////////////////////////////////////////////////////////
/// Send a command to the FTP server
////////////////////////////////////////////////////////////
Ftp::Response Ftp::SendCommand(const std::string& Command, const std::string& Parameter)
{
// Build the command string
std::string CommandStr;
if (Parameter != "")
CommandStr = Command + " " + Parameter + "\r\n";
else
CommandStr = Command + "\r\n";
// Send it to the server
if (myCommandSocket.Send(CommandStr.c_str(), CommandStr.length()) != sf::Socket::Done)
return Response(Response::ConnectionClosed);
// Get the response
return GetResponse();
}
////////////////////////////////////////////////////////////
/// Receive a response from the server
/// (usually after a command has been sent)
////////////////////////////////////////////////////////////
Ftp::Response Ftp::GetResponse()
{
// We'll use a variable to keep track of the last valid code.
// It is useful in case of multi-lines responses, because the end of such a response
// will start by the same code
unsigned int LastCode = 0;
bool IsInsideMultiline = false;
std::string Message;
for (;;)
{
// Receive the response from the server
char Buffer[1024];
std::size_t Length;
if (myCommandSocket.Receive(Buffer, sizeof(Buffer), Length) != sf::Socket::Done)
return Response(Response::ConnectionClosed);
// There can be several lines inside the received buffer, extract them all
std::istringstream In(std::string(Buffer, Length), std::ios_base::binary);
while (In)
{
// Try to extract the code
unsigned int Code;
if (In >> Code)
{
// Extract the separator
char Sep;
In.get(Sep);
// The '-' character means a multiline response
if ((Sep == '-') && !IsInsideMultiline)
{
// Set the multiline flag
IsInsideMultiline = true;
// Keep track of the code
if (LastCode == 0)
LastCode = Code;
// Extract the line
std::getline(In, Message);
// Remove the ending '\r' (all lines are terminated by "\r\n")
Message.erase(Message.length() - 1);
Message = Sep + Message + "\n";
}
else
{
// We must make sure that the code is the same, otherwise it means
// we haven't reached the end of the multiline response
if ((Sep != '-') && ((Code == LastCode) || (LastCode == 0)))
{
// Clear the multiline flag
IsInsideMultiline = false;
// Extract the line
std::string Line;
std::getline(In, Line);
// Remove the ending '\r' (all lines are terminated by "\r\n")
Line.erase(Line.length() - 1);
// Append it to the message
if (Code == LastCode)
{
std::ostringstream Out;
Out << Code << Sep << Line;
Message += Out.str();
}
else
{
Message = Sep + Line;
}
// Return the response code and message
return Response(static_cast<Response::Status>(Code), Message);
}
else
{
// The line we just read was actually not a response,
// only a new part of the current multiline response
// Extract the line
std::string Line;
std::getline(In, Line);
if (!Line.empty())
{
// Remove the ending '\r' (all lines are terminated by "\r\n")
Line.erase(Line.length() - 1);
// Append it to the current message
std::ostringstream Out;
Out << Code << Sep << Line << "\n";
Message += Out.str();
}
}
}
}
else if (LastCode != 0)
{
// It seems we are in the middle of a multiline response
// Clear the error bits of the stream
In.clear();
// Extract the line
std::string Line;
std::getline(In, Line);
if (!Line.empty())
{
// Remove the ending '\r' (all lines are terminated by "\r\n")
Line.erase(Line.length() - 1);
// Append it to the current message
Message += Line + "\n";
}
}
else
{
// Error : cannot extract the code, and we are not in a multiline response
return Response(Response::InvalidResponse);
}
}
}
// We never reach there
}
////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////
Ftp::DataChannel::DataChannel(Ftp& Owner) :
myFtp(Owner)
{
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
Ftp::DataChannel::~DataChannel()
{
// Close the data socket
myDataSocket.Close();
}
////////////////////////////////////////////////////////////
/// Open the data channel using the specified mode and port
////////////////////////////////////////////////////////////
Ftp::Response Ftp::DataChannel::Open(Ftp::TransferMode Mode)
{
// Open a data connection in active mode (we connect to the server)
Ftp::Response Resp = myFtp.SendCommand("PASV");
if (Resp.IsOk())
{
// Extract the connection address and port from the response
std::string::size_type begin = Resp.GetMessage().find_first_of("0123456789");
if (begin != std::string::npos)
{
sf::Uint8 Data[6] = {0, 0, 0, 0, 0, 0};
std::string Str = Resp.GetMessage().substr(begin);
std::size_t Index = 0;
for (int i = 0; i < 6; ++i)
{
// Extract the current number
while (isdigit(Str[Index]))
{
Data[i] = Data[i] * 10 + (Str[Index] - '0');
Index++;
}
// Skip separator
Index++;
}
// Reconstruct connection port and address
unsigned short Port = Data[4] * 256 + Data[5];
sf::IPAddress Address(static_cast<sf::Uint8>(Data[0]),
static_cast<sf::Uint8>(Data[1]),
static_cast<sf::Uint8>(Data[2]),
static_cast<sf::Uint8>(Data[3]));
// Connect the data channel to the server
if (myDataSocket.Connect(Port, Address) == Socket::Done)
{
// Translate the transfer mode to the corresponding FTP parameter
std::string ModeStr;
switch (Mode)
{
case Ftp::Binary : ModeStr = "I"; break;
case Ftp::Ascii : ModeStr = "A"; break;
case Ftp::Ebcdic : ModeStr = "E"; break;
}
// Set the transfer mode
Resp = myFtp.SendCommand("TYPE", ModeStr);
}
else
{
// Failed to connect to the server
Resp = Ftp::Response(Ftp::Response::ConnectionFailed);
}
}
}
return Resp;
}
////////////////////////////////////////////////////////////
/// Receive data on the data channel until it is closed
////////////////////////////////////////////////////////////
void Ftp::DataChannel::Receive(std::vector<char>& Data)
{
// Receive data
Data.clear();
char Buffer[1024];
std::size_t Received;
while (myDataSocket.Receive(Buffer, sizeof(Buffer), Received) == sf::Socket::Done)
{
std::copy(Buffer, Buffer + Received, std::back_inserter(Data));
}
// Close the data socket
myDataSocket.Close();
}
////////////////////////////////////////////////////////////
/// Send data on the data channel
////////////////////////////////////////////////////////////
void Ftp::DataChannel::Send(const std::vector<char>& Data)
{
// Send data
myDataSocket.Send(&Data[0], Data.size());
// Close the data socket
myDataSocket.Close();
}
} // namespace sf

View File

@ -1,425 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Http.hpp>
#include <ctype.h>
#include <sstream>
namespace
{
////////////////////////////////////////////////////////////
// Convenience function to convert a string to lower case
////////////////////////////////////////////////////////////
std::string ToLower(const std::string& Str)
{
std::string Ret = Str;
for (std::string::iterator i = Ret.begin(); i != Ret.end(); ++i)
*i = static_cast<char>(tolower(*i));
return Ret;
}
}
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Http::Request::Request(Method RequestMethod, const std::string& URI, const std::string& Body) :
myMethod (RequestMethod),
myURI (URI),
myMajorVersion(1),
myMinorVersion(0),
myBody (Body)
{
}
////////////////////////////////////////////////////////////
/// Set the value of a field; the field is added if it doesn't exist
////////////////////////////////////////////////////////////
void Http::Request::SetField(const std::string& Field, const std::string& Value)
{
myFields[ToLower(Field)] = Value;
}
////////////////////////////////////////////////////////////
/// Set the request method.
/// This parameter is Get by default
////////////////////////////////////////////////////////////
void Http::Request::SetMethod(Http::Request::Method RequestMethod)
{
myMethod = RequestMethod;
}
////////////////////////////////////////////////////////////
/// Set the target URI of the request.
/// This parameter is "/" by default
////////////////////////////////////////////////////////////
void Http::Request::SetURI(const std::string& URI)
{
myURI = URI;
// Make sure it starts with a '/'
if (myURI.empty() || (myURI[0] != '/'))
myURI.insert(0, "/");
}
////////////////////////////////////////////////////////////
/// Set the HTTP version of the request.
/// This parameter is 1.0 by default
////////////////////////////////////////////////////////////
void Http::Request::SetHttpVersion(unsigned int Major, unsigned int Minor)
{
myMajorVersion = Major;
myMinorVersion = Minor;
}
////////////////////////////////////////////////////////////
/// Set the body of the request. This parameter is optional and
/// makes sense only for POST requests.
/// This parameter is empty by default
////////////////////////////////////////////////////////////
void Http::Request::SetBody(const std::string& Body)
{
myBody = Body;
}
////////////////////////////////////////////////////////////
/// Get the string representation of a request header
////////////////////////////////////////////////////////////
std::string Http::Request::ToString() const
{
std::ostringstream Out;
// Convert the method to its string representation
std::string RequestMethod;
switch (myMethod)
{
default :
case Get : RequestMethod = "GET"; break;
case Post : RequestMethod = "POST"; break;
case Head : RequestMethod = "HEAD"; break;
}
// Write the first line containing the request type
Out << RequestMethod << " " << myURI << " ";
Out << "HTTP/" << myMajorVersion << "." << myMinorVersion << "\r\n";
// Write fields
for (FieldTable::const_iterator i = myFields.begin(); i != myFields.end(); ++i)
{
Out << i->first << ": " << i->second << "\r\n";
}
// Use an extra \r\n to separate the header from the body
Out << "\r\n";
// Add the body
Out << myBody;
return Out.str();
}
////////////////////////////////////////////////////////////
/// Check if the given field has been defined
////////////////////////////////////////////////////////////
bool Http::Request::HasField(const std::string& Field) const
{
return myFields.find(Field) != myFields.end();
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Http::Response::Response() :
myStatus (ConnectionFailed),
myMajorVersion(0),
myMinorVersion(0)
{
}
////////////////////////////////////////////////////////////
/// Get the value of a field
////////////////////////////////////////////////////////////
const std::string& Http::Response::GetField(const std::string& Field) const
{
FieldTable::const_iterator It = myFields.find(Field);
if (It != myFields.end())
{
return It->second;
}
else
{
static const std::string Empty = "";
return Empty;
}
}
////////////////////////////////////////////////////////////
/// Get the header's status code
////////////////////////////////////////////////////////////
Http::Response::Status Http::Response::GetStatus() const
{
return myStatus;
}
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
////////////////////////////////////////////////////////////
unsigned int Http::Response::GetMajorHttpVersion() const
{
return myMajorVersion;
}
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
////////////////////////////////////////////////////////////
unsigned int Http::Response::GetMinorHttpVersion() const
{
return myMinorVersion;
}
////////////////////////////////////////////////////////////
/// Get the body of the response. The body can contain :
/// - the requested page (for GET requests)
/// - a response from the server (for POST requests)
/// - nothing (for HEAD requests)
/// - an error message (in case of an error)
////////////////////////////////////////////////////////////
const std::string& Http::Response::GetBody() const
{
return myBody;
}
////////////////////////////////////////////////////////////
/// Construct the header from a response string
////////////////////////////////////////////////////////////
void Http::Response::FromString(const std::string& Data)
{
std::istringstream In(Data);
// Extract the HTTP version from the first line
std::string Version;
if (In >> Version)
{
if ((Version.size() >= 8) && (Version[6] == '.') &&
(ToLower(Version.substr(0, 5)) == "http/") &&
isdigit(Version[5]) && isdigit(Version[7]))
{
myMajorVersion = Version[5] - '0';
myMinorVersion = Version[7] - '0';
}
else
{
// Invalid HTTP version
myStatus = InvalidResponse;
return;
}
}
// Extract the status code from the first line
int StatusCode;
if (In >> StatusCode)
{
myStatus = static_cast<Status>(StatusCode);
}
else
{
// Invalid status code
myStatus = InvalidResponse;
return;
}
// Ignore the end of the first line
In.ignore(10000, '\n');
// Parse the other lines, which contain fields, one by one
std::string Line;
while (std::getline(In, Line) && (Line.size() > 2))
{
std::string::size_type Pos = Line.find(": ");
if (Pos != std::string::npos)
{
// Extract the field name and its value
std::string Field = Line.substr(0, Pos);
std::string Value = Line.substr(Pos + 2);
// Remove any trailing \r
if (!Value.empty() && (*Value.rbegin() == '\r'))
Value.erase(Value.size() - 1);
// Add the field
myFields[ToLower(Field)] = Value;
}
}
// Finally extract the body
myBody.clear();
while (std::getline(In, Line))
myBody += Line + "\n";
}
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Http::Http() :
myHost(),
myPort(0)
{
}
////////////////////////////////////////////////////////////
/// Construct the Http instance with the target host
////////////////////////////////////////////////////////////
Http::Http(const std::string& Host, unsigned short Port)
{
SetHost(Host, Port);
}
////////////////////////////////////////////////////////////
/// Set the target host
////////////////////////////////////////////////////////////
void Http::SetHost(const std::string& Host, unsigned short Port)
{
// Detect the protocol used
std::string Protocol = ToLower(Host.substr(0, 8));
if (Protocol.substr(0, 7) == "http://")
{
// HTTP protocol
myHostName = Host.substr(7);
myPort = (Port != 0 ? Port : 80);
}
else if (Protocol == "https://")
{
// HTTPS protocol
myHostName = Host.substr(8);
myPort = (Port != 0 ? Port : 443);
}
else
{
// Undefined protocol - use HTTP
myHostName = Host;
myPort = (Port != 0 ? Port : 80);
}
// Remove any trailing '/' from the host name
if (!myHostName.empty() && (*myHostName.rbegin() == '/'))
myHostName.erase(myHostName.size() - 1);
myHost = sf::IPAddress(myHostName);
}
////////////////////////////////////////////////////////////
/// Send a HTTP request and return the server's response.
/// You must be connected to a host before sending requests.
/// Any missing mandatory header field will be added with an appropriate value.
/// Warning : this function waits for the server's response and may
/// not return instantly; use a thread if you don't want to block your
/// application.
////////////////////////////////////////////////////////////
Http::Response Http::SendRequest(const Http::Request& Req, float Timeout)
{
// First make sure the request is valid -- add missing mandatory fields
Request ToSend(Req);
if (!ToSend.HasField("From"))
{
ToSend.SetField("From", "user@sfml-dev.org");
}
if (!ToSend.HasField("User-Agent"))
{
ToSend.SetField("User-Agent", "libsfml-network/1.x");
}
if (!ToSend.HasField("Host"))
{
ToSend.SetField("Host", myHostName);
}
if (!ToSend.HasField("Content-Length"))
{
std::ostringstream Out;
Out << ToSend.myBody.size();
ToSend.SetField("Content-Length", Out.str());
}
// Prepare the response
Response Received;
// Connect the socket to the host
if (myConnection.Connect(myPort, myHost, Timeout) == Socket::Done)
{
// Convert the request to string and send it through the connected socket
std::string RequestStr = ToSend.ToString();
if (!RequestStr.empty())
{
// Send it through the socket
if (myConnection.Send(RequestStr.c_str(), RequestStr.size()) == sf::Socket::Done)
{
// Wait for the server's response
std::string ReceivedStr;
std::size_t Size = 0;
char Buffer[1024];
while (myConnection.Receive(Buffer, sizeof(Buffer), Size) == sf::Socket::Done)
{
ReceivedStr.append(Buffer, Buffer + Size);
}
// Build the Response object from the received data
Received.FromString(ReceivedStr);
}
}
// Close the connection
myConnection.Close();
}
return Received;
}
} // namespace sf

View File

@ -1,298 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/Http.hpp>
#include <SFML/Network/SocketHelper.hpp>
#include <string.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// Static member data
////////////////////////////////////////////////////////////
const IPAddress IPAddress::LocalHost("127.0.0.1");
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
IPAddress::IPAddress() :
myAddress(INADDR_NONE)
{
}
////////////////////////////////////////////////////////////
/// Construct the address from a string
////////////////////////////////////////////////////////////
IPAddress::IPAddress(const std::string& Address)
{
// First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
myAddress = inet_addr(Address.c_str());
// If not successful, try to convert it as a host name
if (!IsValid())
{
hostent* Host = gethostbyname(Address.c_str());
if (Host)
{
// Host found, extract its IP address
myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
}
else
{
// Host name not found on the network
myAddress = INADDR_NONE;
}
}
}
////////////////////////////////////////////////////////////
/// Construct the address from a C-style string ;
/// Needed for implicit conversions from literal strings to IPAddress to work
////////////////////////////////////////////////////////////
IPAddress::IPAddress(const char* Address)
{
// First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
myAddress = inet_addr(Address);
// If not successful, try to convert it as a host name
if (!IsValid())
{
hostent* Host = gethostbyname(Address);
if (Host)
{
// Host found, extract its IP address
myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
}
else
{
// Host name not found on the network
myAddress = INADDR_NONE;
}
}
}
////////////////////////////////////////////////////////////
/// Construct the address from 4 bytes
////////////////////////////////////////////////////////////
IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3)
{
myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
}
////////////////////////////////////////////////////////////
/// Construct the address from a 32-bits integer
////////////////////////////////////////////////////////////
IPAddress::IPAddress(Uint32 Address)
{
myAddress = htonl(Address);
}
////////////////////////////////////////////////////////////
/// Tell if the address is a valid one
////////////////////////////////////////////////////////////
bool IPAddress::IsValid() const
{
return myAddress != INADDR_NONE;
}
////////////////////////////////////////////////////////////
/// Get a string representation of the address
////////////////////////////////////////////////////////////
std::string IPAddress::ToString() const
{
in_addr InAddr;
InAddr.s_addr = myAddress;
return inet_ntoa(InAddr);
}
////////////////////////////////////////////////////////////
/// Get an integer representation of the address
////////////////////////////////////////////////////////////
Uint32 IPAddress::ToInteger() const
{
return ntohl(myAddress);
}
////////////////////////////////////////////////////////////
/// Get the computer's local IP address (from the LAN point of view)
////////////////////////////////////////////////////////////
IPAddress IPAddress::GetLocalAddress()
{
// The method here is to connect a UDP socket to anyone (here to localhost),
// and get the local socket address with the getsockname function.
// UDP connection will not send anything to the network, so this function won't cause any overhead.
IPAddress LocalAddress;
// Create the socket
SocketHelper::SocketType Socket = socket(PF_INET, SOCK_DGRAM, 0);
if (Socket == SocketHelper::InvalidSocket())
return LocalAddress;
// Build the host address (use a random port)
sockaddr_in SockAddr;
memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
SockAddr.sin_addr.s_addr = INADDR_LOOPBACK;
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(4567);
// Connect the socket
if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
{
SocketHelper::Close(Socket);
return LocalAddress;
}
// Get the local address of the socket connection
SocketHelper::LengthType Size = sizeof(SockAddr);
if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1)
{
SocketHelper::Close(Socket);
return LocalAddress;
}
// Close the socket
SocketHelper::Close(Socket);
// Finally build the IP address
LocalAddress.myAddress = SockAddr.sin_addr.s_addr;
return LocalAddress;
}
////////////////////////////////////////////////////////////
/// Get the computer's public IP address (from the web point of view)
////////////////////////////////////////////////////////////
IPAddress IPAddress::GetPublicAddress(float Timeout)
{
// The trick here is more complicated, because the only way
// to get our public IP address is to get it from a distant computer.
// Here we get the web page from http://www.sfml-dev.org/ip-provider.php
// and parse the result to extract our IP address
// (not very hard : the web page contains only our IP address).
Http Server("www.sfml-dev.org");
Http::Request Request(Http::Request::Get, "/ip-provider.php");
Http::Response Page = Server.SendRequest(Request, Timeout);
if (Page.GetStatus() == Http::Response::Ok)
return IPAddress(Page.GetBody());
// Something failed: return an invalid address
return IPAddress();
}
////////////////////////////////////////////////////////////
/// Comparison operator ==
////////////////////////////////////////////////////////////
bool IPAddress::operator ==(const IPAddress& Other) const
{
return myAddress == Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Comparison operator !=
////////////////////////////////////////////////////////////
bool IPAddress::operator !=(const IPAddress& Other) const
{
return myAddress != Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Comparison operator <
////////////////////////////////////////////////////////////
bool IPAddress::operator <(const IPAddress& Other) const
{
return myAddress < Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Comparison operator >
////////////////////////////////////////////////////////////
bool IPAddress::operator >(const IPAddress& Other) const
{
return myAddress > Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Comparison operator <=
////////////////////////////////////////////////////////////
bool IPAddress::operator <=(const IPAddress& Other) const
{
return myAddress <= Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Comparison operator >=
////////////////////////////////////////////////////////////
bool IPAddress::operator >=(const IPAddress& Other) const
{
return myAddress >= Other.myAddress;
}
////////////////////////////////////////////////////////////
/// Operator >> overload to extract an address from an input stream
////////////////////////////////////////////////////////////
std::istream& operator >>(std::istream& Stream, IPAddress& Address)
{
std::string Str;
Stream >> Str;
Address = IPAddress(Str);
return Stream;
}
////////////////////////////////////////////////////////////
/// Operator << overload to print an address to an output stream
////////////////////////////////////////////////////////////
std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address)
{
return Stream << Address.ToString();
}
} // namespace sf

View File

@ -1,426 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Packet.hpp>
#include <SFML/Network/SocketHelper.hpp>
#include <string.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
Packet::Packet() :
myReadPos(0),
myIsValid(true)
{
}
////////////////////////////////////////////////////////////
/// Virtual destructor
////////////////////////////////////////////////////////////
Packet::~Packet()
{
}
////////////////////////////////////////////////////////////
/// Append data to the end of the packet
////////////////////////////////////////////////////////////
void Packet::Append(const void* Data, std::size_t SizeInBytes)
{
if (Data && (SizeInBytes > 0))
{
std::size_t Start = myData.size();
myData.resize(Start + SizeInBytes);
memcpy(&myData[Start], Data, SizeInBytes);
}
}
////////////////////////////////////////////////////////////
/// Clear the packet data
////////////////////////////////////////////////////////////
void Packet::Clear()
{
myData.clear();
myReadPos = 0;
myIsValid = true;
}
////////////////////////////////////////////////////////////
/// Get a pointer to the data contained in the packet
/// Warning : the returned pointer may be invalid after you
/// append data to the packet
////////////////////////////////////////////////////////////
const char* Packet::GetData() const
{
return !myData.empty() ? &myData[0] : NULL;
}
////////////////////////////////////////////////////////////
/// Get the size of the data contained in the packet
////////////////////////////////////////////////////////////
std::size_t Packet::GetDataSize() const
{
return myData.size();
}
////////////////////////////////////////////////////////////
/// Tell if the reading position has reached the end of the packet
////////////////////////////////////////////////////////////
bool Packet::EndOfPacket() const
{
return myReadPos >= myData.size();
}
////////////////////////////////////////////////////////////
/// Tell if the packet is valid for reading
////////////////////////////////////////////////////////////
Packet::operator bool() const
{
return myIsValid;
}
////////////////////////////////////////////////////////////
/// Operator >> overloads to extract data from the packet
////////////////////////////////////////////////////////////
Packet& Packet::operator >>(bool& Data)
{
Uint8 Value;
if (*this >> Value)
Data = (Value != 0);
return *this;
}
Packet& Packet::operator >>(Int8& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = *reinterpret_cast<const Int8*>(GetData() + myReadPos);
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(Uint8& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = *reinterpret_cast<const Uint8*>(GetData() + myReadPos);
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(Int16& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = ntohs(*reinterpret_cast<const Int16*>(GetData() + myReadPos));
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(Uint16& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = ntohs(*reinterpret_cast<const Uint16*>(GetData() + myReadPos));
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(Int32& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = ntohl(*reinterpret_cast<const Int32*>(GetData() + myReadPos));
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(Uint32& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = ntohl(*reinterpret_cast<const Uint32*>(GetData() + myReadPos));
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(float& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = *reinterpret_cast<const float*>(GetData() + myReadPos);
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(double& Data)
{
if (CheckSize(sizeof(Data)))
{
Data = *reinterpret_cast<const double*>(GetData() + myReadPos);
myReadPos += sizeof(Data);
}
return *this;
}
Packet& Packet::operator >>(char* Data)
{
// First extract string length
Uint32 Length;
*this >> Length;
if ((Length > 0) && CheckSize(Length))
{
// Then extract characters
memcpy(Data, GetData() + myReadPos, Length);
Data[Length] = '\0';
// Update reading position
myReadPos += Length;
}
return *this;
}
Packet& Packet::operator >>(std::string& Data)
{
// First extract string length
Uint32 Length;
*this >> Length;
Data.clear();
if ((Length > 0) && CheckSize(Length))
{
// Then extract characters
Data.assign(GetData() + myReadPos, Length);
// Update reading position
myReadPos += Length;
}
return *this;
}
Packet& Packet::operator >>(wchar_t* Data)
{
// First extract string length
Uint32 Length;
*this >> Length;
if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
{
// Then extract characters
for (Uint32 i = 0; i < Length; ++i)
{
Uint32 c;
*this >> c;
Data[i] = static_cast<wchar_t>(c);
}
Data[Length] = L'\0';
}
return *this;
}
Packet& Packet::operator >>(std::wstring& Data)
{
// First extract string length
Uint32 Length;
*this >> Length;
Data.clear();
if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
{
// Then extract characters
for (Uint32 i = 0; i < Length; ++i)
{
Uint32 c;
*this >> c;
Data += static_cast<wchar_t>(c);
}
}
return *this;
}
////////////////////////////////////////////////////////////
/// Operator << overloads to put data into the packet
////////////////////////////////////////////////////////////
Packet& Packet::operator <<(bool Data)
{
*this << static_cast<Uint8>(Data);
return *this;
}
Packet& Packet::operator <<(Int8 Data)
{
Append(&Data, sizeof(Data));
return *this;
}
Packet& Packet::operator <<(Uint8 Data)
{
Append(&Data, sizeof(Data));
return *this;
}
Packet& Packet::operator <<(Int16 Data)
{
Int16 ToWrite = htons(Data);
Append(&ToWrite, sizeof(ToWrite));
return *this;
}
Packet& Packet::operator <<(Uint16 Data)
{
Uint16 ToWrite = htons(Data);
Append(&ToWrite, sizeof(ToWrite));
return *this;
}
Packet& Packet::operator <<(Int32 Data)
{
Int32 ToWrite = htonl(Data);
Append(&ToWrite, sizeof(ToWrite));
return *this;
}
Packet& Packet::operator <<(Uint32 Data)
{
Uint32 ToWrite = htonl(Data);
Append(&ToWrite, sizeof(ToWrite));
return *this;
}
Packet& Packet::operator <<(float Data)
{
Append(&Data, sizeof(Data));
return *this;
}
Packet& Packet::operator <<(double Data)
{
Append(&Data, sizeof(Data));
return *this;
}
Packet& Packet::operator <<(const char* Data)
{
// First insert string length
Uint32 Length = 0;
for (const char* c = Data; *c != '\0'; ++c)
++Length;
*this << Length;
// Then insert characters
Append(Data, Length * sizeof(char));
return *this;
}
Packet& Packet::operator <<(const std::string& Data)
{
// First insert string length
Uint32 Length = static_cast<Uint32>(Data.size());
*this << Length;
// Then insert characters
if (Length > 0)
{
Append(Data.c_str(), Length * sizeof(std::string::value_type));
}
return *this;
}
Packet& Packet::operator <<(const wchar_t* Data)
{
// First insert string length
Uint32 Length = 0;
for (const wchar_t* c = Data; *c != L'\0'; ++c)
++Length;
*this << Length;
// Then insert characters
for (const wchar_t* c = Data; *c != L'\0'; ++c)
*this << static_cast<Int32>(*c);
return *this;
}
Packet& Packet::operator <<(const std::wstring& Data)
{
// First insert string length
Uint32 Length = static_cast<Uint32>(Data.size());
*this << Length;
// Then insert characters
if (Length > 0)
{
for (std::wstring::const_iterator c = Data.begin(); c != Data.end(); ++c)
*this << static_cast<Int32>(*c);
}
return *this;
}
////////////////////////////////////////////////////////////
/// Check if the packet can extract a given size of bytes
////////////////////////////////////////////////////////////
bool Packet::CheckSize(std::size_t Size)
{
myIsValid = myIsValid && (myReadPos + Size <= myData.size());
return myIsValid;
}
////////////////////////////////////////////////////////////
/// Called before the packet is sent to the network
////////////////////////////////////////////////////////////
const char* Packet::OnSend(std::size_t& DataSize)
{
DataSize = GetDataSize();
return GetData();
}
////////////////////////////////////////////////////////////
/// Called after the packet has been received from the network
////////////////////////////////////////////////////////////
void Packet::OnReceive(const char* Data, std::size_t DataSize)
{
Append(Data, DataSize);
}
} // namespace sf

View File

@ -1,132 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifdef _MSC_VER
#pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro
#endif
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SelectorBase.hpp>
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SelectorBase::SelectorBase() :
myMaxSocket(0)
{
Clear();
}
////////////////////////////////////////////////////////////
/// Add a socket to watch
////////////////////////////////////////////////////////////
void SelectorBase::Add(SocketHelper::SocketType Socket)
{
FD_SET(Socket, &mySet);
int Size = static_cast<int>(Socket);
if (Size > myMaxSocket)
myMaxSocket = Size;
}
////////////////////////////////////////////////////////////
/// Remove a socket
////////////////////////////////////////////////////////////
void SelectorBase::Remove(SocketHelper::SocketType Socket)
{
FD_CLR(Socket, &mySet);
}
////////////////////////////////////////////////////////////
/// Remove all sockets
////////////////////////////////////////////////////////////
void SelectorBase::Clear()
{
FD_ZERO(&mySet);
FD_ZERO(&mySetReady);
myMaxSocket = 0;
}
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
////////////////////////////////////////////////////////////
unsigned int SelectorBase::Wait(float Timeout)
{
// Setup the timeout structure
timeval Time;
Time.tv_sec = static_cast<long>(Timeout);
Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000;
// Prepare the set of sockets to return
mySetReady = mySet;
// Wait until one of the sockets is ready for reading, or timeout is reached
int NbSockets = select(myMaxSocket + 1, &mySetReady, NULL, NULL, Timeout > 0 ? &Time : NULL);
return NbSockets >= 0 ? static_cast<unsigned int>(NbSockets) : 0;
}
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
////////////////////////////////////////////////////////////
SocketHelper::SocketType SelectorBase::GetSocketReady(unsigned int Index)
{
// The standard FD_xxx interface doesn't define a direct access,
// so we must go through the whole set to find the socket we're looking for
for (int i = 0; i < myMaxSocket + 1; ++i)
{
if (FD_ISSET(i, &mySetReady))
{
// Current socket is ready, but is it the Index-th one ?
if (Index > 0)
{
Index--;
}
else
{
return static_cast<SocketHelper::SocketType>(i);
}
}
}
// Invalid index : return an invalid socket
return SocketHelper::InvalidSocket();
}
} // namespace sf

View File

@ -1,501 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/Packet.hpp>
#include <SFML/Network/SocketHelper.hpp>
#include <algorithm>
#include <iostream>
#include <string.h>
#ifdef _MSC_VER
#pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro
#endif
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SocketTCP::SocketTCP()
{
Create(SocketHelper::InvalidSocket());
}
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket
////////////////////////////////////////////////////////////
void SocketTCP::SetBlocking(bool Blocking)
{
// Make sure our socket is valid
if (!IsValid())
Create();
SocketHelper::SetBlocking(mySocket, Blocking);
myIsBlocking = Blocking;
}
////////////////////////////////////////////////////////////
/// Connect to another computer on a specified port
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout)
{
// Make sure our socket is valid
if (!IsValid())
Create();
// Build the host address
sockaddr_in SockAddr;
memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str());
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(Port);
if (Timeout <= 0)
{
// ----- We're not using a timeout : just try to connect -----
if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
{
// Failed to connect
return SocketHelper::GetErrorStatus();
}
// Connection succeeded
return Socket::Done;
}
else
{
// ----- We're using a timeout : we'll need a few tricks to make it work -----
// Save the previous blocking state
bool IsBlocking = myIsBlocking;
// Switch to non-blocking to enable our connection timeout
if (IsBlocking)
SetBlocking(false);
// Try to connect to host
if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0)
{
// We got instantly connected! (it may no happen a lot...)
return Socket::Done;
}
// Get the error status
Socket::Status Status = SocketHelper::GetErrorStatus();
// If we were in non-blocking mode, return immediatly
if (!IsBlocking)
return Status;
// Otherwise, wait until something happens to our socket (success, timeout or error)
if (Status == Socket::NotReady)
{
// Setup the selector
fd_set Selector;
FD_ZERO(&Selector);
FD_SET(mySocket, &Selector);
// Setup the timeout
timeval Time;
Time.tv_sec = static_cast<long>(Timeout);
Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000;
// Wait for something to write on our socket (which means that the connection request has returned)
if (select(static_cast<int>(mySocket + 1), NULL, &Selector, NULL, &Time) > 0)
{
// At this point the connection may have been either accepted or refused.
// To know whether it's a success or a failure, we try to retrieve the name of the connected peer
SocketHelper::LengthType Size = sizeof(SockAddr);
if (getpeername(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) != -1)
{
// Connection accepted
Status = Socket::Done;
}
else
{
// Connection failed
Status = SocketHelper::GetErrorStatus();
}
}
else
{
// Failed to connect before timeout is over
Status = SocketHelper::GetErrorStatus();
}
}
// Switch back to blocking mode
SetBlocking(true);
return Status;
}
}
////////////////////////////////////////////////////////////
/// Listen to a specified port for incoming data or connections
////////////////////////////////////////////////////////////
bool SocketTCP::Listen(unsigned short Port)
{
// Make sure our socket is valid
if (!IsValid())
Create();
// Build the address
sockaddr_in SockAddr;
memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(Port);
// Bind the socket to the specified port
if (bind(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
{
// Not likely to happen, but...
std::cerr << "Failed to bind socket to port " << Port << std::endl;
return false;
}
// Listen to the bound port
if (listen(mySocket, 0) == -1)
{
// Oops, socket is deaf
std::cerr << "Failed to listen to port " << Port << std::endl;
return false;
}
return true;
}
////////////////////////////////////////////////////////////
/// Wait for a connection (must be listening to a port).
/// This function will block if the socket is blocking
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Accept(SocketTCP& Connected, IPAddress* Address)
{
// Address that will be filled with client informations
sockaddr_in ClientAddress;
SocketHelper::LengthType Length = sizeof(ClientAddress);
// Accept a new connection
Connected = accept(mySocket, reinterpret_cast<sockaddr*>(&ClientAddress), &Length);
// Check errors
if (!Connected.IsValid())
{
if (Address)
*Address = IPAddress();
return SocketHelper::GetErrorStatus();
}
// Fill address if requested
if (Address)
*Address = IPAddress(inet_ntoa(ClientAddress.sin_addr));
return Socket::Done;
}
////////////////////////////////////////////////////////////
/// Send an array of bytes to the host (must be connected first)
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Send(const char* Data, std::size_t Size)
{
// First check that socket is valid
if (!IsValid())
return Socket::Error;
// Check parameters
if (Data && Size)
{
// Loop until every byte has been sent
int Sent = 0;
int SizeToSend = static_cast<int>(Size);
for (int Length = 0; Length < SizeToSend; Length += Sent)
{
// Send a chunk of data
Sent = send(mySocket, Data + Length, SizeToSend - Length, 0);
// Check if an error occured
if (Sent <= 0)
return SocketHelper::GetErrorStatus();
}
return Socket::Done;
}
else
{
// Error...
std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
return Socket::Error;
}
}
////////////////////////////////////////////////////////////
/// Receive an array of bytes from the host (must be connected first).
/// This function will block if the socket is blocking
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived)
{
// First clear the size received
SizeReceived = 0;
// Check that socket is valid
if (!IsValid())
return Socket::Error;
// Check parameters
if (Data && MaxSize)
{
// Receive a chunk of bytes
int Received = recv(mySocket, Data, static_cast<int>(MaxSize), 0);
// Check the number of bytes received
if (Received > 0)
{
SizeReceived = static_cast<std::size_t>(Received);
return Socket::Done;
}
else if (Received == 0)
{
return Socket::Disconnected;
}
else
{
return SocketHelper::GetErrorStatus();
}
}
else
{
// Error...
std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
return Socket::Error;
}
}
////////////////////////////////////////////////////////////
/// Send a packet of data to the host (must be connected first)
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Send(Packet& PacketToSend)
{
// Get the data to send from the packet
std::size_t DataSize = 0;
const char* Data = PacketToSend.OnSend(DataSize);
// Send the packet size
Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize));
Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize));
// Send the packet data
if (PacketSize > 0)
{
return Send(Data, DataSize);
}
else
{
return Socket::Done;
}
}
////////////////////////////////////////////////////////////
/// Receive a packet from the host (must be connected first).
/// This function will block if the socket is blocking
////////////////////////////////////////////////////////////
Socket::Status SocketTCP::Receive(Packet& PacketToReceive)
{
// We start by getting the size of the incoming packet
Uint32 PacketSize = 0;
std::size_t Received = 0;
if (myPendingPacketSize < 0)
{
Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received);
if (Status != Socket::Done)
return Status;
PacketSize = ntohl(PacketSize);
}
else
{
// There is a pending packet : we already know its size
PacketSize = myPendingPacketSize;
}
// Then loop until we receive all the packet data
char Buffer[1024];
while (myPendingPacket.size() < PacketSize)
{
// Receive a chunk of data
std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer));
Socket::Status Status = Receive(Buffer, SizeToGet, Received);
if (Status != Socket::Done)
{
// We must save the size of the pending packet until we can receive its content
if (Status == Socket::NotReady)
myPendingPacketSize = PacketSize;
return Status;
}
// Append it into the packet
if (Received > 0)
{
myPendingPacket.resize(myPendingPacket.size() + Received);
char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received;
memcpy(Begin, Buffer, Received);
}
}
// We have received all the datas : we can copy it to the user packet, and clear our internal packet
PacketToReceive.Clear();
if (!myPendingPacket.empty())
PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size());
myPendingPacket.clear();
myPendingPacketSize = -1;
return Socket::Done;
}
////////////////////////////////////////////////////////////
/// Close the socket
////////////////////////////////////////////////////////////
bool SocketTCP::Close()
{
if (IsValid())
{
if (!SocketHelper::Close(mySocket))
{
std::cerr << "Failed to close socket" << std::endl;
return false;
}
mySocket = SocketHelper::InvalidSocket();
}
myIsBlocking = true;
return true;
}
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
////////////////////////////////////////////////////////////
bool SocketTCP::IsValid() const
{
return mySocket != SocketHelper::InvalidSocket();
}
////////////////////////////////////////////////////////////
/// Comparison operator ==
////////////////////////////////////////////////////////////
bool SocketTCP::operator ==(const SocketTCP& Other) const
{
return mySocket == Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Comparison operator !=
////////////////////////////////////////////////////////////
bool SocketTCP::operator !=(const SocketTCP& Other) const
{
return mySocket != Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
////////////////////////////////////////////////////////////
bool SocketTCP::operator <(const SocketTCP& Other) const
{
return mySocket < Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
////////////////////////////////////////////////////////////
SocketTCP::SocketTCP(SocketHelper::SocketType Descriptor)
{
Create(Descriptor);
}
////////////////////////////////////////////////////////////
/// Create the socket
////////////////////////////////////////////////////////////
void SocketTCP::Create(SocketHelper::SocketType Descriptor)
{
// Use the given socket descriptor, or get a new one
mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_STREAM, 0);
myIsBlocking = true;
// Reset the pending packet
myPendingPacket.clear();
myPendingPacketSize = -1;
// Setup default options
if (IsValid())
{
// To avoid the "Address already in use" error message when trying to bind to the same port
int Yes = 1;
if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
{
std::cerr << "Failed to set socket option \"SO_REUSEADDR\" ; "
<< "binding to a same port may fail if too fast" << std::endl;
}
// Disable the Nagle algorithm (ie. removes buffering of TCP packets)
if (setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
{
std::cerr << "Failed to set socket option \"TCP_NODELAY\" ; "
<< "all your TCP packets will be buffered" << std::endl;
}
// Set blocking by default (should always be the case anyway)
SetBlocking(true);
}
}
} // namespace sf

View File

@ -1,430 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketUDP.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/Packet.hpp>
#include <algorithm>
#include <iostream>
#include <string.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SocketUDP::SocketUDP()
{
Create();
}
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket
////////////////////////////////////////////////////////////
void SocketUDP::SetBlocking(bool Blocking)
{
// Make sure our socket is valid
if (!IsValid())
Create();
SocketHelper::SetBlocking(mySocket, Blocking);
myIsBlocking = Blocking;
}
////////////////////////////////////////////////////////////
/// Bind the socket to a specific port
////////////////////////////////////////////////////////////
bool SocketUDP::Bind(unsigned short Port)
{
// Check if the socket is already bound to the specified port
if (myPort != Port)
{
// If the socket was previously bound to another port, we need to unbind it first
Unbind();
if (Port != 0)
{
// Build an address with the specified port
sockaddr_in Addr;
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = INADDR_ANY;
memset(Addr.sin_zero, 0, sizeof(Addr.sin_zero));
// Bind the socket to the port
if (bind(mySocket, reinterpret_cast<sockaddr*>(&Addr), sizeof(Addr)) == -1)
{
std::cerr << "Failed to bind the socket to port " << Port << std::endl;
myPort = 0;
return false;
}
}
// Save the new port
myPort = Port;
}
return true;
}
////////////////////////////////////////////////////////////
/// Unbind the socket to its previous port
////////////////////////////////////////////////////////////
bool SocketUDP::Unbind()
{
// To unbind the socket, we just recreate it
if (myPort != 0)
{
Close();
Create();
myPort = 0;
}
return true;
}
////////////////////////////////////////////////////////////
/// Send an array of bytes
////////////////////////////////////////////////////////////
Socket::Status SocketUDP::Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port)
{
// Make sure the socket is valid
if (!IsValid())
Create();
// Check parameters
if (Data && Size)
{
// Build the target address
sockaddr_in Target;
Target.sin_family = AF_INET;
Target.sin_port = htons(Port);
Target.sin_addr.s_addr = inet_addr(Address.ToString().c_str());
memset(Target.sin_zero, 0, sizeof(Target.sin_zero));
// Loop until every byte has been sent
int Sent = 0;
int SizeToSend = static_cast<int>(Size);
for (int Length = 0; Length < SizeToSend; Length += Sent)
{
// Send a chunk of data
Sent = sendto(mySocket, Data + Length, SizeToSend - Length, 0, reinterpret_cast<sockaddr*>(&Target), sizeof(Target));
// Check errors
if (Sent <= 0)
return SocketHelper::GetErrorStatus();
}
return Socket::Done;
}
else
{
// Error...
std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
return Socket::Error;
}
}
////////////////////////////////////////////////////////////
/// Receive an array of bytes.
/// This function will block if the socket is blocking
////////////////////////////////////////////////////////////
Socket::Status SocketUDP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address, unsigned short& Port)
{
// First clear the size received
SizeReceived = 0;
// Make sure the socket is bound to a port
if (myPort == 0)
{
std::cerr << "Failed to receive data ; the UDP socket first needs to be bound to a port" << std::endl;
return Socket::Error;
}
// Make sure the socket is valid
if (!IsValid())
Create();
// Check parameters
if (Data && MaxSize)
{
// Data that will be filled with the other computer's address
sockaddr_in Sender;
Sender.sin_family = AF_INET;
Sender.sin_port = 0;
Sender.sin_addr.s_addr = INADDR_ANY;
memset(Sender.sin_zero, 0, sizeof(Sender.sin_zero));
SocketHelper::LengthType SenderSize = sizeof(Sender);
// Receive a chunk of bytes
int Received = recvfrom(mySocket, Data, static_cast<int>(MaxSize), 0, reinterpret_cast<sockaddr*>(&Sender), &SenderSize);
// Check the number of bytes received
if (Received > 0)
{
Address = IPAddress(inet_ntoa(Sender.sin_addr));
Port = ntohs(Sender.sin_port);
SizeReceived = static_cast<std::size_t>(Received);
return Socket::Done;
}
else
{
Address = IPAddress();
Port = 0;
return Received == 0 ? Socket::Disconnected : SocketHelper::GetErrorStatus();
}
}
else
{
// Error...
std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
return Socket::Error;
}
}
////////////////////////////////////////////////////////////
/// Send a packet of data
////////////////////////////////////////////////////////////
Socket::Status SocketUDP::Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port)
{
// Get the data to send from the packet
std::size_t DataSize = 0;
const char* Data = PacketToSend.OnSend(DataSize);
// Send the packet size
Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize));
Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize), Address, Port);
// Send the packet data
if (PacketSize > 0)
{
return Send(Data, DataSize, Address, Port);
}
else
{
return Socket::Done;
}
}
////////////////////////////////////////////////////////////
/// Receive a packet.
/// This function will block if the socket is blocking
////////////////////////////////////////////////////////////
Socket::Status SocketUDP::Receive(Packet& PacketToReceive, IPAddress& Address, unsigned short& Port)
{
// This is not safe at all, as data can be lost, duplicated, or arrive in a different order.
// So if a packet is split into more than one chunk, nobody knows what could happen...
// Conclusion : we shouldn't use packets with UDP, unless we build a more complex protocol on top of it.
// We start by getting the size of the incoming packet
Uint32 PacketSize = 0;
std::size_t Received = 0;
if (myPendingPacketSize < 0)
{
Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received, Address, Port);
if (Status != Socket::Done)
return Status;
PacketSize = ntohl(PacketSize);
}
else
{
// There is a pending packet : we already know its size
PacketSize = myPendingPacketSize;
}
// Clear the user packet
PacketToReceive.Clear();
// Use another address instance for receiving the packet data ;
// chunks of data coming from a different sender will be discarded (and lost...)
IPAddress Sender;
unsigned short SenderPort;
// Then loop until we receive all the packet data
char Buffer[1024];
while (myPendingPacket.size() < PacketSize)
{
// Receive a chunk of data
std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer));
Socket::Status Status = Receive(Buffer, SizeToGet, Received, Sender, SenderPort);
if (Status != Socket::Done)
{
// We must save the size of the pending packet until we can receive its content
if (Status == Socket::NotReady)
myPendingPacketSize = PacketSize;
return Status;
}
// Append it into the packet
if ((Sender == Address) && (SenderPort == Port) && (Received > 0))
{
myPendingPacket.resize(myPendingPacket.size() + Received);
char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received;
memcpy(Begin, Buffer, Received);
}
}
// We have received all the datas : we can copy it to the user packet, and clear our internal packet
PacketToReceive.Clear();
if (!myPendingPacket.empty())
PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size());
myPendingPacket.clear();
myPendingPacketSize = -1;
return Socket::Done;
}
////////////////////////////////////////////////////////////
/// Close the socket
////////////////////////////////////////////////////////////
bool SocketUDP::Close()
{
if (IsValid())
{
if (!SocketHelper::Close(mySocket))
{
std::cerr << "Failed to close socket" << std::endl;
return false;
}
mySocket = SocketHelper::InvalidSocket();
}
myPort = 0;
myIsBlocking = true;
return true;
}
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
////////////////////////////////////////////////////////////
bool SocketUDP::IsValid() const
{
return mySocket != SocketHelper::InvalidSocket();
}
////////////////////////////////////////////////////////////
/// Get the port the socket is currently bound to
////////////////////////////////////////////////////////////
unsigned short SocketUDP::GetPort() const
{
return myPort;
}
////////////////////////////////////////////////////////////
/// Comparison operator ==
////////////////////////////////////////////////////////////
bool SocketUDP::operator ==(const SocketUDP& Other) const
{
return mySocket == Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Comparison operator !=
////////////////////////////////////////////////////////////
bool SocketUDP::operator !=(const SocketUDP& Other) const
{
return mySocket != Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
////////////////////////////////////////////////////////////
bool SocketUDP::operator <(const SocketUDP& Other) const
{
return mySocket < Other.mySocket;
}
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
////////////////////////////////////////////////////////////
SocketUDP::SocketUDP(SocketHelper::SocketType Descriptor)
{
Create(Descriptor);
}
////////////////////////////////////////////////////////////
/// Create the socket
////////////////////////////////////////////////////////////
void SocketUDP::Create(SocketHelper::SocketType Descriptor)
{
// Use the given socket descriptor, or get a new one
mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_DGRAM, 0);
myIsBlocking = true;
// Clear the last port used
myPort = 0;
// Reset the pending packet
myPendingPacket.clear();
myPendingPacketSize = -1;
// Setup default options
if (IsValid())
{
// To avoid the "Address already in use" error message when trying to bind to the same port
int Yes = 1;
if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
{
std::cerr << "Failed to set socket option \"reuse address\" ; "
<< "binding to a same port may fail if too fast" << std::endl;
}
// Enable broadcast by default
if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
{
std::cerr << "Failed to enable broadcast on UDP socket" << std::endl;
}
// Set blocking by default (should always be the case anyway)
SetBlocking(true);
}
}
} // namespace sf

View File

@ -1,89 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
#include <errno.h>
#include <fcntl.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
////////////////////////////////////////////////////////////
SocketHelper::SocketType SocketHelper::InvalidSocket()
{
return -1;
}
////////////////////////////////////////////////////////////
/// Close / destroy a socket
////////////////////////////////////////////////////////////
bool SocketHelper::Close(SocketHelper::SocketType Socket)
{
return close(Socket) != -1;
}
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
////////////////////////////////////////////////////////////
void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block)
{
int Status = fcntl(Socket, F_GETFL);
if (Block)
fcntl(Socket, F_SETFL, Status & ~O_NONBLOCK);
else
fcntl(Socket, F_SETFL, Status | O_NONBLOCK);
}
////////////////////////////////////////////////////////////
/// Get the last socket error status
////////////////////////////////////////////////////////////
Socket::Status SocketHelper::GetErrorStatus()
{
// The followings are sometimes equal to EWOULDBLOCK,
// so we have to make a special case for them in order
// to avoid having double values in the switch case
if ((errno == EAGAIN) || (errno == EINPROGRESS))
return Socket::NotReady;
switch (errno)
{
case EWOULDBLOCK : return Socket::NotReady;
case ECONNABORTED : return Socket::Disconnected;
case ECONNRESET : return Socket::Disconnected;
case ETIMEDOUT : return Socket::Disconnected;
case ENETRESET : return Socket::Disconnected;
case ENOTCONN : return Socket::Disconnected;
default : return Socket::Error;
}
}
} // namespace sf

View File

@ -1,100 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
namespace sf
{
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
////////////////////////////////////////////////////////////
SocketHelper::SocketType SocketHelper::InvalidSocket()
{
return INVALID_SOCKET;
}
////////////////////////////////////////////////////////////
/// Close / destroy a socket
////////////////////////////////////////////////////////////
bool SocketHelper::Close(SocketHelper::SocketType Socket)
{
return closesocket(Socket) != -1;
}
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
////////////////////////////////////////////////////////////
void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block)
{
unsigned long Blocking = Block ? 0 : 1;
ioctlsocket(Socket, FIONBIO, &Blocking);
}
////////////////////////////////////////////////////////////
/// Get the last socket error status
////////////////////////////////////////////////////////////
Socket::Status SocketHelper::GetErrorStatus()
{
switch (WSAGetLastError())
{
case WSAEWOULDBLOCK : return Socket::NotReady;
case WSAECONNABORTED : return Socket::Disconnected;
case WSAECONNRESET : return Socket::Disconnected;
case WSAETIMEDOUT : return Socket::Disconnected;
case WSAENETRESET : return Socket::Disconnected;
case WSAENOTCONN : return Socket::Disconnected;
default : return Socket::Error;
}
}
////////////////////////////////////////////////////////////
// Windows needs some initialization and cleanup to get
// sockets working properly... so let's create a class that will
// do it automatically
////////////////////////////////////////////////////////////
struct SocketInitializer
{
SocketInitializer()
{
WSADATA InitData;
WSAStartup(MAKEWORD(2,2), &InitData);
}
~SocketInitializer()
{
WSACleanup();
}
};
SocketInitializer GlobalInitializer;
} // namespace sf

Some files were not shown because too many files have changed in this diff Show More