This commit is contained in:
parent
4a0fe6cfd2
commit
0e8dbcb2bd
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -1,5 +0,0 @@
|
|||
/* 7zHeader.c */
|
||||
|
||||
#include "7zHeader.h"
|
||||
|
||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
@ -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
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -1,10 +0,0 @@
|
|||
/* 7zMethodID.c */
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
/*
|
||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
|
||||
{
|
||||
return (*a1 == *a2) ? 1 : 0;
|
||||
}
|
||||
*/
|
|
@ -1,10 +0,0 @@
|
|||
/* 7zMethodID.h */
|
||||
|
||||
#ifndef __7Z_METHOD_ID_H
|
||||
#define __7Z_METHOD_ID_H
|
||||
|
||||
#include "../../Types.h"
|
||||
|
||||
typedef UInt64 CMethodID;
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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=""$(ProjectDir)..\zlib""
|
||||
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=""$(ProjectDir)..\zlib""
|
||||
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>
|
|
@ -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>
|
|
@ -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
|
Binary file not shown.
|
@ -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>
|
|
@ -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>
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 ); }
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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!
|
||||
|
||||
|
|
@ -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
|
|
@ -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.
|
@ -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.
|
|
@ -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=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
|
||||
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=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
|
||||
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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue