Restructure repository to include all source folders

Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
// AuthTest.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include "../NFAuthClient/AuthClient.h"
#include <conio.h>
void ShowHelp()
{
printf("\n--------------------------------\n");
printf("H : help\n");
printf("H : help\n");
printf("Q : quit\n");
printf("S : Send IRC Packet\n");
printf("A : Send Auth Packet\n");
printf("--------------------------------\n");
}
int main(int argc, CHAR* argv[])
{
char strMD5[40];
GetMD5(argv[0], strMD5);
printf(strMD5);
printf("\n");
CPacketEvent event;
DWORD dwConnectTick = timeGetTime();
if(!g_NetAuth.Init("192.168.0.7", 14050))
{
printf("error!!\n");
return 0;
}
g_NetAuth.SetEventListener(&event);
g_IPSec.LoadAllowIPZ(L"./AllowIPList.bin");
bool bExit = false;
while(!bExit)
{
if(kbhit())
{
char ch = getch();
switch(ch)
{
case 'h':
ShowHelp();
break;
case 'q':
bExit = true;
break;
case 's':
g_NetAuth.Send_IRC("/SND", "테스트패킷전송");
break;
case 'a':
GetMD5(argv[0], strMD5);
g_NetAuth.Send_AUTH(MAKEWPARAM(AT_LOGIN, 0), strMD5);
break;
case 'l':
g_NetAuth.Send_CMD(CS_IPLIST, 0);
break;
}
}
if(abs(timeGetTime()-dwConnectTick) > 5000)
{
dwConnectTick = timeGetTime();
if(!g_NetAuth.IsConnect())
g_NetAuth.Init("192.168.0.7", 14050);
}
g_NetAuth.Update();
Sleep(1);
}
printf("exit...\n");
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,32 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthTest", "AuthTest.vcproj", "{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}"
ProjectSection(ProjectDependencies) = postProject
{17A72D81-FF95-4EC9-970A-C6C8232C33DB} = {17A72D81-FF95-4EC9-970A-C6C8232C33DB}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NFAuthClient", "..\NFAuthClient\NFAuthClient.vcproj", "{17A72D81-FF95-4EC9-970A-C6C8232C33DB}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}.Debug.ActiveCfg = Debug|Win32
{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}.Debug.Build.0 = Debug|Win32
{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}.Release.ActiveCfg = Release|Win32
{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}.Release.Build.0 = Release|Win32
{17A72D81-FF95-4EC9-970A-C6C8232C33DB}.Debug.ActiveCfg = Debug|Win32
{17A72D81-FF95-4EC9-970A-C6C8232C33DB}.Debug.Build.0 = Debug|Win32
{17A72D81-FF95-4EC9-970A-C6C8232C33DB}.Release.ActiveCfg = Release|Win32
{17A72D81-FF95-4EC9-970A-C6C8232C33DB}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

Binary file not shown.

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="AuthTest"
ProjectGUID="{4B4CB5C9-932A-4B48-AA99-236F0C668AA0}"
RootNamespace="AuthTest"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../Executable/$(ConfigurationName)"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../NFAuthClient"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="NFAuthClient.lib"
OutputFile="$(OutDir)/AuthTest.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\NFAuthClient; ..\NFAuthClient\SDK\Lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/AuthTest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../Executable/$(ConfigurationName)"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/AuthTest.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\NFAuthClient; ..\NFAuthClient\SDK\Lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="소스 파일"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\AuthTest.cpp">
</File>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="헤더 파일"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\stdafx.h">
</File>
</Filter>
<Filter
Name="리소스 파일"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,32 @@
========================================================================
콘솔 응용 프로그램 : AuthTest 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 AuthTest 응용 프로그램을 만들었습니다.
이 파일에는 AuthTest 응용 프로그램을 구성하는 각각의 파일에
들어 있는 요약 설명이 포함되어 있습니다.
AuthTest.vcproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
프로젝트 기능에 대한 정보가 들어 있습니다.
AuthTest.cpp
기본 응용 프로그램 소스 파일입니다.
/////////////////////////////////////////////////////////////////////////////
기타 표준 파일:
StdAfx.h 및 StdAfx.cpp는
AuthTest.pch라는 이름의 PCH(미리 컴파일된 헤더) 파일과
StdAfx.obj라는 이름의 미리 컴파일된 형식 파일을 빌드하는 데 사용됩니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,8 @@
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
// AuthTest.pch는 미리 컴파일된 헤더가 됩니다.
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
#include "stdafx.h"
// TODO: 필요한 추가 헤더는
// 이 파일이 아닌 STDAFX.H에서 참조합니다.

View File

@@ -0,0 +1,12 @@
// stdafx.h : 자주 사용하지만 자주 변경되지는 않는
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
// 들어 있는 포함 파일입니다.
//
#pragma once
#include <iostream>
#include <tchar.h>
// TODO: 프로그램에 필요한 추가 헤더는 여기에서 참조합니다.

View File

@@ -0,0 +1,134 @@
#include "AuthClient.h"
#include <conio.h>
#include "Nave/NFFilePtr.h"
extern "C"
{
#include "MD5/global.h"
#include "MD5/md5.h"
}
void GetMD5(char* file, char* outMD5)
{
///////////////////////////////////////////////////////////////////////////////
// MD5를 구하는 함수
// 파일을 로드한다.
char* fileDat = NULL;
long len;
if(1)
{
Nave::NFFilePtr fp(file, "rb");
len = fp.Length();
fileDat = new char[len];
fread(fileDat, len, 1, fp);
}
MD5_CTX context;
unsigned char digest[16] ;
memset( digest, 0, sizeof( char ) * 16 ) ;
MD5Init(&context);
MD5Update(&context, reinterpret_cast<unsigned char *>( fileDat ), len );
MD5Final(digest, &context);
char strMD5[40];
ZeroMemory(strMD5, sizeof(strMD5));
for (int i = 0; i < 16; ++i)
{
sprintf(strMD5 + i * 2, "%02x", digest[i]);
}
if(fileDat)
delete fileDat;
strcpy(outMD5, strMD5);
}
CNetAuth g_NetAuth;
NFIPSec g_IPSec;
CPacketEvent::CPacketEvent()
{
}
CPacketEvent::~CPacketEvent()
{
}
void CPacketEvent::EventIRC(CHAR* strCmd, CHAR* strMsg)
{
// printf("%s : %s\n", strCmd, strMsg);
}
void CPacketEvent::EventCMD(DWORD dwCmd, DWORD dwValue)
{
// 여기서 결과에 따라서 게임서버를 종료하던지 기타 다른 행동을 하던지 한다.
// printf("Command : %d (%d)\n", dwCmd, dwValue);
switch(dwCmd)
{
case SC_SHUTDOWN: // 종료한다.
exit(0); // 어플리케이션을 종료한다.
break;
}
}
void CPacketEvent::EventIPLIST(CHAR Type, CHAR Page, SHORT Count, char* lpIPList_Out)
{
LPIPINFO ipInfo = (LPIPINFO)lpIPList_Out;
if(Page == 1)
{
if(Type == 0)
{
g_IPSec.ClearAllowIP();
// printf("============= Allow IP ==============\n");
}
else if(Type == 1)
{
g_IPSec.ClearBlockIP();
// printf("============= Block IP ==============\n");
}
}
g_IPSec.SerializeIn(Type, Count, lpIPList_Out);
/*
int aC = g_IPSec.GetAllowIPCount();
char ip1[32];
char ip2[32];
sockaddr_in sip1, sip2;
for(int i = 0; i < Count; ++i)
{
sip1.sin_addr.s_addr = htonl(ipInfo->start);
sip2.sin_addr.s_addr = htonl(ipInfo->end);
strcpy(ip1,inet_ntoa(sip1.sin_addr));
strcpy(ip2,inet_ntoa(sip2.sin_addr));
printf("%s - %s\n", ip1, ip2 );
ipInfo++;
}
*/
}
void CPacketEvent::EventConnect(BOOL bConnect)
{
/*
if(bConnect)
printf("Connect\n");
else
printf("Connect Faild\n");
*/
}
void CPacketEvent::EventSocketClose()
{
// printf("Disconnect\n");
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "NetAuth.h"
#include "NFIPSec.h"
extern CNetAuth g_NetAuth;
extern NFIPSec g_IPSec;
void GetMD5(char* file, char* outMD5);
class CPacketEvent : public CNetAuth::IEventListener
{
public:
CPacketEvent();
~CPacketEvent();
public:
virtual void EventIRC(CHAR* strCmd, CHAR* strMsg);
virtual void EventCMD(DWORD dwCmd, DWORD dwValue);
virtual void EventIPLIST(CHAR Type, CHAR Page, SHORT Count, char* lpIPList_Out);
virtual void EventConnect(BOOL bConnect);
virtual void EventSocketClose();
};

View File

@@ -0,0 +1,30 @@
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 1
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif

View File

@@ -0,0 +1,37 @@
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));

View File

@@ -0,0 +1,337 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "global.h"
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0xa2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0xa4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@@ -0,0 +1,267 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="NFAuthClient"
ProjectGUID="{17A72D81-FF95-4EC9-970A-C6C8232C33DB}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="./"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/NFAuthClient.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../Executable/$(ConfigurationName)"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/NFAuthClient.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="MD5"
Filter="">
<File
RelativePath=".\MD5\global.h">
</File>
<File
RelativePath=".\MD5\md5.h">
</File>
<File
RelativePath=".\MD5\md5c.c">
</File>
</Filter>
<Filter
Name="Nave"
Filter="">
<File
RelativePath=".\Nave\NFFilePtr.h">
</File>
<File
RelativePath=".\Nave\NFTokenizer.cpp">
</File>
<File
RelativePath=".\Nave\NFTokenizer.h">
</File>
</Filter>
<Filter
Name="NaveNet"
Filter="">
<File
RelativePath=".\NaveNet\NFIOBuffer.cpp">
</File>
<File
RelativePath=".\NaveNet\NFIOBuffer.h">
</File>
<File
RelativePath=".\NaveNet\NFNet.cpp">
</File>
<File
RelativePath=".\NaveNet\NFNet.h">
</File>
<File
RelativePath=".\NaveNet\NFNetClientS.cpp">
</File>
<File
RelativePath=".\NaveNet\NFNetClientS.h">
</File>
<File
RelativePath=".\NaveNet\NFPacket.cpp">
</File>
<File
RelativePath=".\NaveNet\NFPacket.h">
</File>
<File
RelativePath=".\NaveNet\NFSync.h">
</File>
<Filter
Name="GZip"
Filter="">
<File
RelativePath=".\NaveNet\GZip\adler32.c">
</File>
<File
RelativePath=".\NaveNet\GZip\compress.c">
</File>
<File
RelativePath=".\NaveNet\GZip\crc32.c">
</File>
<File
RelativePath=".\NaveNet\GZip\crc32.h">
</File>
<File
RelativePath=".\NaveNet\GZip\deflate.c">
</File>
<File
RelativePath=".\NaveNet\GZip\deflate.h">
</File>
<File
RelativePath=".\NaveNet\GZip\gzio.c">
</File>
<File
RelativePath=".\NaveNet\GZip\gzip.cpp">
</File>
<File
RelativePath=".\NaveNet\GZip\gzip.h">
</File>
<File
RelativePath=".\NaveNet\GZip\infback.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inffast.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inffast.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inffixed.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inflate.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inflate.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inftrees.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inftrees.h">
</File>
<File
RelativePath=".\NaveNet\GZip\trees.c">
</File>
<File
RelativePath=".\NaveNet\GZip\trees.h">
</File>
<File
RelativePath=".\NaveNet\GZip\uncompr.c">
</File>
<File
RelativePath=".\NaveNet\GZip\zconf.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zconf.in.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zlib.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zutil.c">
</File>
<File
RelativePath=".\NaveNet\GZip\zutil.h">
</File>
</Filter>
</Filter>
<Filter
Name="SDK"
Filter="">
<File
RelativePath=".\SDK\Lib\zlib.lib">
</File>
</Filter>
<File
RelativePath=".\AuthClient.cpp">
</File>
<File
RelativePath=".\AuthClient.h">
</File>
<File
RelativePath=".\NetAuth.cpp">
</File>
<File
RelativePath=".\NetAuth.h">
</File>
<File
RelativePath=".\NFIPSec.cpp">
</File>
<File
RelativePath=".\NFIPSec.h">
</File>
<File
RelativePath=".\Packet.h">
</File>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,361 @@
#include "AuthClient.h"
#include "NFIPSec.h"
#include "Nave/NFTokenizer.h"
#include "NaveNet/GZip/zlib.h"
#pragma comment(lib,"zlib.lib")
NFIPSec::NFIPSec(void)
{
}
NFIPSec::~NFIPSec(void)
{
}
void NFIPSec::LoadAllowIP(WCHAR* lpIPFileName)
{
m_vecAllowIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rt");
if(!fp)
return;
char strBuff[256];
IPBAND ip;
while(true)
{
fgets(strBuff, 256, fp);
if(feof(fp))
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecAllowIP.push_back(ip);
}
fclose(fp);
}
void NFIPSec::LoadBlockIP(WCHAR* lpIPFileName)
{
m_vecBlockIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rt");
if(!fp)
return;
char strBuff[256];
IPBAND ip;
while(true)
{
fgets(strBuff, 256, fp);
if(feof(fp))
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecBlockIP.push_back(ip);
}
fclose(fp);
}
BOOL GetLine( const CHAR* sBuf, INT maxsBuf, CHAR* tBuf, INT maxtBuf, LONG& index )
{
ZeroMemory(tBuf, sizeof(tBuf));
INT DestIndex = index;
CHAR* pLine = "\n";
INT pLen = strlen(pLine);
for(INT i = 0; i < maxsBuf; i++)
{
if(index+i >= maxsBuf)
break;
if(strncmp(&sBuf[index+i], pLine, pLen) == 0)
{
CopyMemory(tBuf, sBuf+index, i);
index += (i+pLen);
tBuf[i] = 0;
return TRUE;
}
}
INT len = maxsBuf-index;
if(maxtBuf <= len)
len = maxtBuf-index;
CopyMemory(tBuf, sBuf+index, len);
tBuf[len] = 0;
index += len;
return FALSE;
}
void NFIPSec::LoadAllowIPZ(WCHAR* lpIPFileName)
{
m_vecAllowIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rb");
if(!fp)
return;
long len = 0;
long datalen = 0;
char szMD5[40];
memset(szMD5, 0, sizeof(szMD5));
fread(&len, sizeof(long), 1, fp);
fread(&datalen, sizeof(long), 1, fp);
fread(szMD5, 32, 1, fp);
char* fileDat = new char[datalen];
fread(fileDat, datalen, 1, fp);
fclose(fp);
// MD5를 이용해 암호화를 합니다.
for(long i = 0; i < datalen; ++i)
{
fileDat[i] = fileDat[i]^szMD5[i%32];
}
char* outDat = new char[len*2];
memset(outDat, 0, sizeof(char)*len*2);
// 파일을 디코딩 합니다.
uLongf destLen = len*2;
uncompress((Bytef*)outDat, &destLen, (Bytef*)fileDat, datalen);
outDat[destLen]=0;
if(fileDat)
delete []fileDat;
LONG index = 0;
char strBuff[256];
IPBAND ip;
BOOL bRet = TRUE;
while(bRet)
{
bRet = GetLine(outDat, destLen, strBuff, 256, index);
if(strlen(strBuff) == 0)
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecAllowIP.push_back(ip);
}
if(outDat)
delete []outDat;
}
void NFIPSec::LoadBlockIPZ(WCHAR* lpIPFileName)
{
m_vecBlockIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rb");
if(!fp)
return;
long len;
long datalen;
char szMD5[40];
memset(szMD5, 0, sizeof(szMD5));
fread(&len, sizeof(long), 1, fp);
fread(&datalen, sizeof(long), 1, fp);
fread(szMD5, 32, 1, fp);
char* fileDat = new char[datalen];
fread(fileDat, datalen, 1, fp);
fclose(fp);
// MD5를 이용해 암호화를 합니다.
for(long i = 0; i < datalen; ++i)
{
fileDat[i] = fileDat[i]^szMD5[i%32];
}
char* outDat = new char[len*2];
// 파일을 디코딩 합니다.
uLongf destLen = len*2;
uncompress((Bytef*)outDat, &destLen, (Bytef*)fileDat, datalen);
outDat[destLen]=0;
if(fileDat)
delete []fileDat;
LONG index = 0;
char strBuff[256];
IPBAND ip;
BOOL bRet = TRUE;
while(bRet)
{
bRet = GetLine(outDat, destLen, strBuff, 256, index);
if(strlen(strBuff) == 0)
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecBlockIP.push_back(ip);
}
if(outDat)
delete []outDat;
}
BOOL NFIPSec::IsAliveIP(const char * strIP)
{
return IsAliveIP(inet_addr(strIP));
}
BOOL NFIPSec::IsAliveIP(unsigned long dwIP)
{
if(CheckBlockIP(dwIP))
return FALSE;
return CheckAllowIP(dwIP);
}
BOOL NFIPSec::CheckAllowIP(const char * strIP)
{
return CheckAllowIP(inet_addr(strIP));
}
BOOL NFIPSec::CheckAllowIP(unsigned long dwIP)
{
// 바이트를 뒤집어준다.
dwIP = htonl(dwIP);
int iCount = (int)m_vecAllowIP.size();
for(int i = 0; i < iCount; ++i)
{
if(m_vecAllowIP[i].start <= dwIP && dwIP <= m_vecAllowIP[i].end)
return TRUE;
}
return FALSE;
}
BOOL NFIPSec::CheckBlockIP(const char * strIP)
{
return CheckBlockIP(inet_addr(strIP));
}
BOOL NFIPSec::CheckBlockIP(unsigned long dwIP)
{
// 바이트를 뒤집어준다.
dwIP = htonl(dwIP);
int iCount = (int)m_vecBlockIP.size();
for(int i = 0; i < iCount; ++i)
{
if(m_vecBlockIP[i].start <= dwIP && dwIP <= m_vecBlockIP[i].end)
return TRUE;
}
return FALSE;
}
int NFIPSec::SerializeOut(int iType, int iPos, int iCount, char* lpBuffer_Out)
{
LPIPBAND ipOut = (LPIPBAND)lpBuffer_Out;
LPIPBAND ipCur;
int iLast = iPos+iCount;
if(iType == 0)
{
if(m_vecAllowIP.empty())
return 0;
if(iLast >= (int)m_vecAllowIP.size())
{
iLast = (int)m_vecAllowIP.size();
iCount = iLast-iPos;
}
for(int i = iPos; i < iLast; ++i, ++ipOut)
{
ipCur = &m_vecAllowIP[i];
ipOut->start = ipCur->start;
ipOut->end = ipCur->end;
}
return iCount;
}
else if(iType == 1)
{
if(m_vecBlockIP.empty())
return 0;
if(iLast >= (int)m_vecBlockIP.size())
{
iLast = (int)m_vecBlockIP.size();
iCount = iLast-iPos;
}
for(int i = iPos; i < iLast; ++i, ++ipOut)
{
ipCur = &m_vecBlockIP[i];
ipOut->start = ipCur->start;
ipOut->end = ipCur->end;
}
return iCount;
}
return 0;
}
void NFIPSec::SerializeIn(int iType, int iCount, char* lpBuffer_In)
{
LPIPBAND ipIn = (LPIPBAND)lpBuffer_In;
if(iType == 0)
{
for(int i = 0; i < iCount; ++i, ++ipIn)
m_vecAllowIP.push_back(*ipIn);
}
else if(iType == 1)
{
for(int i = 0; i < iCount; ++i, ++ipIn)
m_vecBlockIP.push_back(*ipIn);
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include <vector>
typedef struct IPBAND
{
DWORD start;
DWORD end;
}*LPIPBAND;
class NFIPSec
{
public:
NFIPSec(void);
~NFIPSec(void);
public:
void LoadAllowIP(WCHAR* lpIPFileName);
void LoadBlockIP(WCHAR* lpIPFileName);
void LoadAllowIPZ(WCHAR* lpIPFileName);
void LoadBlockIPZ(WCHAR* lpIPFileName);
int SerializeOut(int iType, int iPos, int iCount, char* lpBuffer_Out);
void SerializeIn(int iType, int iCount, char* lpBuffer_In);
inline void ClearAllowIP() { m_vecAllowIP.clear(); }
inline void ClearBlockIP() { m_vecBlockIP.clear(); }
BOOL IsAliveIP(const char * strIP);
BOOL IsAliveIP(unsigned long dwIP);
BOOL CheckAllowIP(const char * strIP);
BOOL CheckAllowIP(unsigned long dwIP);
BOOL CheckBlockIP(const char * strIP);
BOOL CheckBlockIP(unsigned long dwIP);
inline int GetAllowIPCount() { return (int)m_vecAllowIP.size(); }
inline int GetBlockIPCount() { return (int)m_vecBlockIP.size(); }
private:
std::vector<IPBAND> m_vecAllowIP;
std::vector<IPBAND> m_vecBlockIP;
};

View File

@@ -0,0 +1,141 @@
/**
* @file NFFilePtr.h
* @brief FILE auto close class
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <stdio.h> // standard I/O
namespace Nave {
/**
* @class NFFilePtr
* @brief FILE auto close class
* @remarks NFFilePtr file(L"c:\\1.txt", L"rt"); \r\n
* fgets(str, 128, file); \r\n
* return;
* @par
* @author Edith
* @date 2009-04-05
*/
class NFFilePtr
{
public:
/// NFFilePtr 생성자
NFFilePtr() : m_pFile(NULL)
{
}
/**
* @brief 파일 자동열기 생성자
* @param file 파일명
* @param mode 파일 모드
*/
NFFilePtr(LPCSTR file, LPCSTR mode)
{
m_pFile = fopen(file, mode);
}
/// NFFilePtr 소멸자
~NFFilePtr()
{
if(m_pFile)
fclose(m_pFile);
m_pFile = NULL;
}
/**
* @brief NFFilePtr1 = FilePtrW2 이터레이터
* @warning NFFilePtr2는 더이상 사용할수 없습니다.
*/
NFFilePtr& operator=(NFFilePtr& _Right) throw()
{
Reset(_Right.Release());
return (*this);
}
/**
* @brief NFFilePtr = FILE* 이터레이터
* @warning NFFilePtr에서 자동 fclose가 됩니다. \r\n
* FILE*객체를 fclose하면 문제가 발생할 수있습니다.
*/
NFFilePtr& operator=(FILE* _Right) throw()
{
Reset(_Right);
return (*this);
}
/**
* @brief FILE* 형변환 오퍼레이터 입니다.
* @return 현재의 파일 포인터
*/
operator FILE*() const throw()
{
return m_pFile;
}
/**
* @brief 파일 포인터를 초기화 합니다. FILE이 close 되지 않습니다.
* @return 현재의 파일 포인터
*/
FILE* Release()
{
FILE* fp = m_pFile;
m_pFile = NULL;
return fp;
}
/**
* @brief 새로운 값으로 재설정합니다. 기존의 FILE은 close 됩니다.
* @param fp 새로운 파일 포인터
*/
void Reset(LPCSTR file, LPCSTR mode)
{
if(m_pFile)
fclose(m_pFile);
m_pFile = fopen(file, mode);
}
/**
* @brief 새로운 값으로 재설정합니다.
* 기존의 FILE은 close 됩니다.
* @param fp 새로운 파일 포인터
*/
void Reset(FILE* fp)
{
if(m_pFile)
fclose(m_pFile);
m_pFile = fp;
}
/**
* @brief 파일의 길이를 리턴합니다.
* @return 파일의 길이
*/
long Length()
{
fpos_t cuspos;
if(fgetpos( m_pFile, &cuspos ) != 0)
return -1; // error
fseek( m_pFile, 0L, SEEK_END );
long length = ftell( m_pFile );
fsetpos(m_pFile, &cuspos);
return length;
}
private:
/// 파일 포인터
FILE* m_pFile;
};
}

View File

@@ -0,0 +1,321 @@
#include "NFTokenizer.h"
namespace Nave {
NFTokenizerA::NFTokenizerA(const std::string& _str, const std::string& _delim)
{
if ((_str.length() == 0) || (_delim.length() == 0)) return;
token_str = _str;
delim = _delim;
/*
Remove sequential delimiter
*/
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::string::npos)
{
curr_pos += delim.length();
while(token_str.find(delim,curr_pos) == curr_pos)
{
token_str.erase(curr_pos,delim.length());
}
}
else
break;
}
/*
Trim leading delimiter
*/
if (token_str.find(delim,0) == 0)
{
token_str.erase(0,delim.length());
}
/*
Trim ending delimiter
*/
curr_pos = 0;
if ((curr_pos = token_str.rfind(delim)) != std::string::npos)
{
if (curr_pos != (token_str.length() - delim.length())) return;
token_str.erase(token_str.length() - delim.length(),delim.length());
}
}
int NFTokenizerA::CountTokens()
{
unsigned int prev_pos = 0;
int num_tokens = 0;
if (token_str.length() > 0)
{
num_tokens = 0;
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::string::npos)
{
num_tokens++;
prev_pos = curr_pos;
curr_pos += delim.length();
}
else
break;
}
return ++num_tokens;
}
else
{
return 0;
}
}
bool NFTokenizerA::HasMoreTokens()
{
return (token_str.length() > 0);
}
std::string NFTokenizerA::NextToken()
{
if (token_str.length() == 0)
return "";
std::string tmp_str = "";
unsigned int pos = token_str.find(delim,0);
if (pos != std::string::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos+delim.length(),token_str.length()-pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = "";
}
return tmp_str;
}
int NFTokenizerA::NextIntToken()
{
return atoi(NextToken().c_str());
}
double NFTokenizerA::NextFloatToken()
{
return atof(NextToken().c_str());
}
std::string NFTokenizerA::NextToken(const std::string& delimiter)
{
if (token_str.length() == 0)
return "";
std::string tmp_str = "";
unsigned int pos = token_str.find(delimiter,0);
if (pos != std::string::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos + delimiter.length(),token_str.length() - pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = "";
}
return tmp_str;
}
std::string& NFTokenizerA::RemainingString()
{
return token_str;
}
std::string NFTokenizerA::FilterNextToken(const std::string& filterStr)
{
std::string tmp_str = NextToken();
unsigned int currentPos = 0;
while((currentPos = tmp_str.find(filterStr,currentPos)) != std::string::npos)
{
tmp_str.erase(currentPos,filterStr.length());
}
return tmp_str;
}
// unicode type
NFTokenizerW::NFTokenizerW(const std::wstring& _str, const std::wstring& _delim)
{
if ((_str.length() == 0) || (_delim.length() == 0)) return;
token_str = _str;
delim = _delim;
/*
Remove sequential delimiter
*/
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::wstring::npos)
{
curr_pos += delim.length();
while(token_str.find(delim,curr_pos) == curr_pos)
{
token_str.erase(curr_pos,delim.length());
}
}
else
break;
}
/*
Trim leading delimiter
*/
if (token_str.find(delim,0) == 0)
{
token_str.erase(0,delim.length());
}
/*
Trim ending delimiter
*/
curr_pos = 0;
if ((curr_pos = token_str.rfind(delim)) != std::wstring::npos)
{
if (curr_pos != (token_str.length() - delim.length())) return;
token_str.erase(token_str.length() - delim.length(),delim.length());
}
}
int NFTokenizerW::CountTokens()
{
unsigned int prev_pos = 0;
int num_tokens = 0;
if (token_str.length() > 0)
{
num_tokens = 0;
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::wstring::npos)
{
num_tokens++;
prev_pos = curr_pos;
curr_pos += delim.length();
}
else
break;
}
return ++num_tokens;
}
else
{
return 0;
}
}
bool NFTokenizerW::HasMoreTokens()
{
return (token_str.length() > 0);
}
std::wstring NFTokenizerW::NextToken()
{
if (token_str.length() == 0)
return L"";
std::wstring tmp_str = L"";
unsigned int pos = token_str.find(delim,0);
if (pos != std::wstring::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos+delim.length(),token_str.length()-pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = L"";
}
return tmp_str;
}
int NFTokenizerW::NextIntToken()
{
return _wtoi(NextToken().c_str());
}
double NFTokenizerW::NextFloatToken()
{
return _wtof(NextToken().c_str());
}
std::wstring NFTokenizerW::NextToken(const std::wstring& delimiter)
{
if (token_str.length() == 0)
return L"";
std::wstring tmp_str = L"";
unsigned int pos = token_str.find(delimiter,0);
if (pos != std::wstring::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos + delimiter.length(),token_str.length() - pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = L"";
}
return tmp_str;
}
std::wstring& NFTokenizerW::RemainingString()
{
return token_str;
}
std::wstring NFTokenizerW::FilterNextToken(const std::wstring& filterStr)
{
std::wstring tmp_str = NextToken();
unsigned int currentPos = 0;
while((currentPos = tmp_str.find(filterStr,currentPos)) != std::wstring::npos)
{
tmp_str.erase(currentPos,filterStr.length());
}
return tmp_str;
}
}

View File

@@ -0,0 +1,120 @@
/**
* @file NFTokenizer.h
* @brief Tokenizer 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
namespace Nave {
/**
* @class NFTokenizerA
* @brief 멀티바이트용 Tokenizer
* @remarks
* Nave::String tempStr = L"01|02|03|04|05|06|07|08|09|10|11|12"; \r\n
* \r\n
* Nave::NFTokenizer strtok = Nave::NFTokenizer(tempStr, L"|"); \r\n
* \r\n
* LOG_IMPORTANT((L"Number Of Tokens: %d"), strtok.CountTokens()); \r\n
* LOG_IMPORTANT((L"String: %s"), strtok.RemainingString().c_str()); \r\n
* \r\n
* int cnt = strtok.CountTokens(); \r\n
* Nave::String finalString = L""; \r\n
* \r\n
* for(int i = 0; i < cnt; i++) \r\n
* { \r\n
* Nave::String tempStr = L""; \r\n
* \r\n
* LOG_IMPORTANT((L"Token[%d] ----> [%s]"), i, strtok.NextToken().c_str());\r\n
* LOG_IMPORTANT((L"Token Count : %d"), strtok.CountTokens()); \r\n
* \r\n
* finalString += tempStr; \r\n
* } \r\n
* \r\n
* LOG_IMPORTANT((L"Final String : %s"), finalString.c_str());
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFTokenizerA
{
public:
NFTokenizerA(const std::string& _str, const std::string& _delim);
~NFTokenizerA(){};
int CountTokens();
bool HasMoreTokens();
std::string NextToken();
int NextIntToken();
double NextFloatToken();
std::string NextToken(const std::string& delim);
std::string& RemainingString();
std::string FilterNextToken(const std::string& filterStr);
private:
std::string token_str;
std::string delim;
};
/**
* @class NFTokenizerW
* @brief 유니코드용 Tokenizer
* @remarks
* Nave::String tempStr = L"01|02|03|04|05|06|07|08|09|10|11|12"; \r\n
* \r\n
* Nave::NFTokenizer strtok = Nave::NFTokenizer(tempStr, L"|"); \r\n
* \r\n
* LOG_IMPORTANT((L"Number Of Tokens: %d"), strtok.CountTokens()); \r\n
* LOG_IMPORTANT((L"String: %s"), strtok.RemainingString().c_str()); \r\n
* \r\n
* int cnt = strtok.CountTokens(); \r\n
* Nave::String finalString = L""; \r\n
* \r\n
* for(int i = 0; i < cnt; i++) \r\n
* { \r\n
* Nave::String tempStr = L""; \r\n
* \r\n
* LOG_IMPORTANT((L"Token[%d] ----> [%s]"), i, strtok.NextToken().c_str());\r\n
* LOG_IMPORTANT((L"Token Count : %d"), strtok.CountTokens()); \r\n
* \r\n
* finalString += tempStr; \r\n
* } \r\n
* \r\n
* LOG_IMPORTANT((L"Final String : %s"), finalString.c_str());
* @par
* @author Edith
* @date 2009-04-05
*/
class NFTokenizerW
{
public:
NFTokenizerW(const std::wstring& _str, const std::wstring& _delim);
~NFTokenizerW(){};
int CountTokens();
bool HasMoreTokens();
std::wstring NextToken();
int NextIntToken();
double NextFloatToken();
std::wstring NextToken(const std::wstring& delim);
std::wstring& RemainingString();
std::wstring FilterNextToken(const std::wstring& filterStr);
private:
std::wstring token_str;
std::wstring delim;
};
typedef NFTokenizerW NFTokenizer;
}

View File

@@ -0,0 +1,272 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="GZip"
ProjectGUID="{14665508-BFE9-4987-92FD-EB4C6307D732}"
RootNamespace="GZip"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../Lib"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Include; ../../;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)\$(ProjectName)_D.lib"
AdditionalLibraryDirectories="../../Library; ../Lib;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../Lib"
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../Include; ../../;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)\$(ProjectName).lib"
AdditionalLibraryDirectories="../../Library; ../Lib;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="¼Ò½º ÆÄÀÏ"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\adler32.c"
>
</File>
<File
RelativePath=".\compress.c"
>
</File>
<File
RelativePath=".\crc32.c"
>
</File>
<File
RelativePath=".\deflate.c"
>
</File>
<File
RelativePath=".\gzio.c"
>
</File>
<File
RelativePath=".\gzip.cpp"
>
</File>
<File
RelativePath=".\infback.c"
>
</File>
<File
RelativePath=".\inffast.c"
>
</File>
<File
RelativePath=".\inflate.c"
>
</File>
<File
RelativePath=".\inftrees.c"
>
</File>
<File
RelativePath=".\trees.c"
>
</File>
<File
RelativePath=".\uncompr.c"
>
</File>
<File
RelativePath=".\zutil.c"
>
</File>
</Filter>
<Filter
Name="Çì´õ ÆÄÀÏ"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\crc32.h"
>
</File>
<File
RelativePath=".\deflate.h"
>
</File>
<File
RelativePath=".\gzip.h"
>
</File>
<File
RelativePath=".\inffast.h"
>
</File>
<File
RelativePath=".\inffixed.h"
>
</File>
<File
RelativePath=".\inflate.h"
>
</File>
<File
RelativePath=".\inftrees.h"
>
</File>
<File
RelativePath=".\trees.h"
>
</File>
<File
RelativePath=".\zconf.h"
>
</File>
<File
RelativePath=".\zconf.in.h"
>
</File>
<File
RelativePath=".\zlib.h"
>
</File>
<File
RelativePath=".\zutil.h"
>
</File>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<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="EDITH"
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="EDITH"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@@ -0,0 +1,22 @@
========================================================================
정적 라이브러리 : GZip 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 GZip 라이브러리를 만들었습니다.
프로젝트에 대해 소스 파일은 만들어지지 않았습니다.
GZip.vcproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
파일을 생성한 Visual C++ 버전에 대한 정보와
응용 프로그램 마법사를 사용하여 선택한 플랫폼, 구성 및 프로젝트 기능에 대한
정보가 들어 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,149 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
#define BASE 65521UL /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
if (a >= (BASE << 16)) a -= (BASE << 16); \
if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
# define MOD4(a) \
do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
# define MOD4(a) a %= BASE
#endif
/* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
unsigned long sum2;
unsigned n;
/* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
/* in case user likes doing a byte at a time, keep it fast */
if (len == 1) {
adler += buf[0];
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
MOD4(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
DO16(buf); /* 16 sums unrolled */
buf += 16;
} while (--n);
MOD(adler);
MOD(sum2);
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
DO16(buf);
buf += 16;
}
while (len--) {
adler += *buf++;
sum2 += adler;
}
MOD(adler);
MOD(sum2);
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
/* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE);
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 > BASE) sum1 -= BASE;
if (sum1 > BASE) sum1 -= BASE;
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 > BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}

View File

@@ -0,0 +1,79 @@
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
/* ===========================================================================
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int level;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = deflateEnd(&stream);
return err;
}
/* ===========================================================================
*/
int ZEXPORT compress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}
/* ===========================================================================
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
{
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
}

View File

@@ -0,0 +1,423 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results in about a
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
/* @(#) $Id$ */
/*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
protection on the static variables used to control the first-use generation
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
*/
#ifdef MAKECRCH
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
# define DYNAMIC_CRC_TABLE
# endif /* !DYNAMIC_CRC_TABLE */
#endif /* MAKECRCH */
#include "zutil.h" /* for STDC and FAR definitions */
#define local static
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
# ifdef STDC /* need ANSI C limits.h to determine sizes */
# include <limits.h>
# define BYFOUR
# if (UINT_MAX == 0xffffffffUL)
typedef unsigned int u4;
# else
# if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long u4;
# else
# if (USHRT_MAX == 0xffffffffUL)
typedef unsigned short u4;
# else
# undef BYFOUR /* can't find a four-byte integer type! */
# endif
# endif
# endif
# endif /* STDC */
#endif /* !NOBYFOUR */
/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
const unsigned char FAR *, unsigned));
# define TBLS 8
#else
# define TBLS 1
#endif /* BYFOUR */
/* Local functions for crc concatenation */
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
#ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1;
local unsigned long FAR crc_table[TBLS][256];
local void make_crc_table OF((void));
#ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The first table is simply the CRC of all possible eight bit values. This is
all the information needed to generate CRCs on data a byte at a time for all
combinations of CRC register values and incoming bytes. The remaining tables
allow for word-at-a-time CRC calculation for both big-endian and little-
endian machines, where a word is four bytes.
*/
local void make_crc_table()
{
unsigned long c;
int n, k;
unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* See if another task is already doing this (not thread-safe, but better
than nothing -- significantly reduces duration of vulnerability in
case the advice about DYNAMIC_CRC_TABLE is ignored) */
if (first) {
first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL;
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
poly |= 1UL << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
}
#ifdef BYFOUR
/* generate crc for each value followed by one, two, and three zeros,
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = REV(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = REV(c);
}
}
#endif /* BYFOUR */
crc_table_empty = 0;
}
else { /* not first */
/* wait for the other guy to finish (not efficient, but rare) */
while (crc_table_empty)
;
}
#ifdef MAKECRCH
/* write out CRC tables to crc32.h */
{
FILE *out;
out = fopen("crc32.h", "w");
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
fprintf(out, "local const unsigned long FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
fprintf(out, "#ifdef BYFOUR\n");
for (k = 1; k < 8; k++) {
fprintf(out, " },\n {\n");
write_table(out, crc_table[k]);
}
fprintf(out, "#endif\n");
# endif /* BYFOUR */
fprintf(out, " }\n};\n");
fclose(out);
}
#endif /* MAKECRCH */
}
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
const unsigned long FAR *table;
{
int n;
for (n = 0; n < 256; n++)
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
#else /* !DYNAMIC_CRC_TABLE */
/* ========================================================================
* Tables of CRC-32s of all single-byte values, made by make_crc_table().
*/
#include "crc32.h"
#endif /* DYNAMIC_CRC_TABLE */
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
const unsigned long FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
return (const unsigned long FAR *)crc_table;
}
/* ========================================================================= */
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
unsigned long ZEXPORT crc32(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
if (buf == Z_NULL) return 0UL;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
#ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) {
u4 endian;
endian = 1;
if (*((unsigned char *)(&endian)))
return crc32_little(crc, buf, len);
else
return crc32_big(crc, buf, len);
}
#endif /* BYFOUR */
crc = crc ^ 0xffffffffUL;
while (len >= 8) {
DO8;
len -= 8;
}
if (len) do {
DO1;
} while (--len);
return crc ^ 0xffffffffUL;
}
#ifdef BYFOUR
/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
local unsigned long crc32_little(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = (u4)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
}
while (len >= 4) {
DOLIT4;
len -= 4;
}
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
} while (--len);
c = ~c;
return (unsigned long)c;
}
/* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
local unsigned long crc32_big(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = REV((u4)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
len -= 32;
}
while (len >= 4) {
DOBIG4;
len -= 4;
}
buf4++;
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
return (unsigned long)(REV(c));
}
#endif /* BYFOUR */
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
local unsigned long gf2_matrix_times(mat, vec)
unsigned long *mat;
unsigned long vec;
{
unsigned long sum;
sum = 0;
while (vec) {
if (vec & 1)
sum ^= *mat;
vec >>= 1;
mat++;
}
return sum;
}
/* ========================================================================= */
local void gf2_matrix_square(square, mat)
unsigned long *square;
unsigned long *mat;
{
int n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off_t len2;
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
/* degenerate case */
if (len2 == 0)
return crc1;
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0)
break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
}

View File

@@ -0,0 +1,441 @@
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
*/
local const unsigned long FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
0x9324fd72UL
},
{
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
0xbe9834edUL
},
{
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
0xde0506f1UL
},
{
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
0x8def022dUL
},
{
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
0x72fd2493UL
},
{
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
0xed3498beUL
},
{
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,331 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef DEFLATE_H
#define DEFLATE_H
#include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
/* ===========================================================================
* Internal compression state.
*/
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
#define COMMENT_STATE 91
#define HCRC_STATE 103
#define BUSY_STATE 113
#define FINISH_STATE 666
/* Stream status */
/* Data structure describing a single value and its code string. */
typedef struct ct_data_s {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} FAR ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
typedef Pos FAR Posf;
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
uInt pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
uInt w_size; /* LZ77 window size (32K by default) */
uInt w_bits; /* log2(w_size) (8..16) */
uInt w_mask; /* w_size - 1 */
Bytef *window;
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least wSize
* bytes. With this organization, matches are limited to a distance of
* wSize-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: use the user input buffer as sliding window.
*/
ulg window_size;
/* Actual size of window: 2*wSize, except when the user input buffer
* is directly used as sliding window.
*/
Posf *prev;
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Posf *head; /* Heads of the hash chains or NIL. */
uInt ins_h; /* hash index of string to be inserted */
uInt hash_size; /* number of elements in hash table */
uInt hash_bits; /* log2(hash_size) */
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* hash_shift * MIN_MATCH >= hash_bits
*/
long block_start;
/* Window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
uInt match_length; /* length of best match */
IPos prev_match; /* previous match */
int match_available; /* set if previous match exists */
uInt strstart; /* start of string to insert */
uInt match_start; /* start of matching string */
uInt lookahead; /* number of valid bytes ahead in window */
uInt prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
uInt max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this
* length. A higher limit improves compression ratio but degrades the
* speed.
*/
uInt max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
# define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length is not
* greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
int level; /* compression level (1..9) */
int strategy; /* favor or force Huffman coding*/
uInt good_match;
/* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
struct tree_desc_s l_desc; /* desc. for literal tree */
struct tree_desc_s d_desc; /* desc. for distance tree */
struct tree_desc_s bl_desc; /* desc. for bit length tree */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
int heap_len; /* number of elements in the heap */
int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
uchf *l_buf; /* buffer for literals or lengths */
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
* limiting lit_bufsize to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input
* data is still in the window so we can still emit a stored block even
* when input comes from standard input. (This can also be done for
* all blocks if lit_bufsize is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* This is applicable only for zip (not gzip or zlib).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting
* trees more frequently.
* - I can't count above 4
*/
uInt last_lit; /* running index in l_buf */
ushf *d_buf;
/* Buffer for distances. To simplify the code, d_buf and l_buf have
* the same number of elements. To use different lengths, an extra flag
* array would be necessary.
*/
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
int last_eob_len; /* bit length of EOB code for last block */
#ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
ush bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
int bi_valid;
/* Number of valid bits in bi_buf. All bits above the last valid bit
* are always zero.
*/
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
/* in trees.c */
void _tr_init OF((deflate_state *s));
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch _length_code[];
extern uch _dist_code[];
#else
extern const uch _length_code[];
extern const uch _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->last_lit] = 0; \
s->l_buf[s->last_lit++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (length); \
ush dist = (distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif /* DEFLATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.1.4, March 11th, 2002
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
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.
Jean-loup Gailly jloup@gzip.org
Mark Adler madler@alumni.caltech.edu
*/
//#include "StdAfx.h"
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
#include <atlconv.h>
#include "zlib.h"
#include "gzip.h"
#include <io.h>
#include <sys/types.h>
#include <fcntl.h>
#include <list>
#include <utility>
#pragma warning(disable : 4996) // vs2005에서 추가됨. 보안상의 이유로 더 이상 사용되지 않는 MFC나 ATL 함수를 사용하는 경우에도 C4996이 발생할 수 있습니다
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
namespace SDK {
bool CZipper::Open(EArchiveMode eArchiveMode)
{
m_eArchiveMode = eArchiveMode;
return true;
}
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
LPCWSTR CZipper::m_stsVersion= WIDEN(ZLIB_VERSION);
CZipper::CZipper()
: m_eCompressionMode(CompressionModeDefault),
m_eArchiveMode(ArchiveModeClosed),
m_eStrategy(StrategyDefault)
{
}
CZipper::~CZipper()
{
}
CGZip::~CGZip()
{
if (IsOpen())
Close();
}
bool CGZip::Open(LPCWSTR szFileName, EArchiveMode eArchiveMode)
{
USES_CONVERSION;
if (IsOpen())
return false;
if (eArchiveMode == ArchiveModeWrite)
{
m_gzf = gzopen(W2CA(szFileName),"wb");
UpdateParams();
}
else if (eArchiveMode == ArchiveModeRead)
{
if (_waccess(szFileName,02))
return false;
// computing file length,
int file=_wopen( szFileName, _O_RDONLY);
if (file==-1)
return false;
m_bufferSize=_filelength(file);
_close(file);
m_gzf = gzopen(W2CA(szFileName),"rb");
}
if (m_gzf != 0)
m_eArchiveMode=eArchiveMode;
else
m_eArchiveMode=ArchiveModeClosed;
return m_gzf != 0;
}
bool CGZip::Close()
{
if (!IsOpen())
return false;
int result = gzclose(m_gzf);
m_gzf=0;
return result == 0;
};
bool CGZip::WriteBuffer( void* pBuffer, size_t nBytes)
{
if (!IsOpen() || !IsWriting())
return false;
int written=gzwrite(m_gzf, pBuffer, nBytes);
return written == (int)(nBytes);
};
bool CGZip::Flush( EFlushMode eFlush)
{
if (!IsOpen() || !IsWriting())
return false;
return gzflush(m_gzf, eFlush)==Z_OK;
}
bool CGZip::WriteString( LPCWSTR str)
{
return WriteBuffer( (void*)str, (wcslen(str)) * sizeof(WCHAR));
};
int CGZip::ReadBuffer( voidp* ppBuffer, size_t& nBytes)
{
using namespace std;
int read;
nBytes=0;
if (!IsOpen() || !IsReading())
return false;
if(!m_bufferSize)
return false;
list< pair < char*,size_t > > lBuffers;
char* pBuffer=NULL;
read=1;
while( read>0)
{
pBuffer=new char[m_bufferSize];
read=gzread(m_gzf, pBuffer, m_bufferSize);
if (read>0)
{
lBuffers.push_back( pair<char*,size_t>( pBuffer,read ) );
nBytes+=read;
}
else
delete pBuffer;
};
if (read== -1)
{
while (!lBuffers.empty())
{
delete[] lBuffers.front().first;
lBuffers.pop_front();
}
return false;
}
// allocating memory and writing buffer
*ppBuffer=new char[nBytes];
size_t offset=0;
while (!lBuffers.empty())
{
pBuffer=lBuffers.front().first;
read=lBuffers.front().second;
memcpy((char*)*ppBuffer+offset, pBuffer, read);
offset+=read;
delete[] pBuffer;
lBuffers.pop_front();
}
return nBytes!=0;
};
int CGZip::ReadString(LPWSTR* ppString)
{
using namespace std;
int read;
size_t nBytes=0;
if (!IsOpen() || !IsReading())
return false;
if(!m_bufferSize)
return false;
list< pair < char*,size_t > > lBuffers;
char* pBuffer=NULL;
read=1;
while( read>0)
{
pBuffer=new char[m_bufferSize];
read=gzread(m_gzf, pBuffer, m_bufferSize);
if (read>0)
{
lBuffers.push_back( pair<char*,size_t>( pBuffer,read ) );
nBytes+=read;
}
else
delete pBuffer;
};
if (read== -1)
{
while (!lBuffers.empty())
{
delete[] lBuffers.front().first;
lBuffers.pop_front();
}
return false;
}
// allocating memory and writing buffer
*ppString=new WCHAR[nBytes+1];
size_t offset=0;
while (!lBuffers.empty())
{
pBuffer=lBuffers.front().first;
read=lBuffers.front().second;
memcpy(((char*)*ppString)+offset, pBuffer, read);
offset+=read;
delete[] pBuffer;
lBuffers.pop_front();
}
(*ppString)[nBytes]='\0';
return nBytes!=0;
}
int CGZip::ReadBufferSize( voidp pBuffer, size_t nBytes)
{
if (!IsOpen() || !IsReading())
return false;
return gzread(m_gzf, pBuffer, nBytes);
}
void CGZip::UpdateParams()
{
if (!IsOpen() || !IsWriting())
return;
gzsetparams( m_gzf, m_eCompressionMode, m_eStrategy);
};
bool CGZip::IsEOF() const
{
if (!IsOpen())
return true;
return gzeof(m_gzf)==1;
}
};

View File

@@ -0,0 +1,464 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.1.4, March 11th, 2002
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
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.
Jean-loup Gailly jloup@gzip.org
Mark Adler madler@alumni.caltech.edu
*/
#pragma once
#include <wchar.h>
#ifndef _ZLIB
#ifndef _ZLIB_INCLUDED
#define _ZLIB_INCLUDED
#pragma message("-----> Adding zlib Library\n")
#pragma comment(lib, "zlib.lib")
#endif
#endif
/*! \mainpage CGZip, a C++ wrapper for gzip
This documents presents CGZip, C++ class wrapper for the gzip methods, which are included in the zlib libary.
The intention of this class is to have a <b>simple</b> class for zipping-unzipping buffers.
The main features of the class are:
- Compress, decompress LPCWSTR to file,
- Compress, decompress memory buffer to file,
- Non-MFC,
- Hides zlib so you don't have to distribute the zlib headers,
- UNICODE compliant.
\author Jonathan de Halleux, dehalleux@pelikhan.com, 2002
\version 1.1
*/
/*!
\defgroup ZlibGroup ZLib Classes
\ingroup PGLGroup
*/
/*! \brief Zlib namespace
\ingroup ZlibGroup
*/
namespace SDK {
class CZipper
{
public:
//! void pointer to void
typedef void* voidp;
//! \brief Archive mode
static enum EArchiveMode
{
//! Archive Mode Closed
ArchiveModeClosed,
//! Writing to file
ArchiveModeWrite = 1,
//! Reading from file
ArchiveModeRead = 2
};
//! \brief Compression mode
static enum ECompressionMode
{
//! no compression
CompressionModeNoCompression= 0,
//! Fast compression
CompressionModeFast = 1,
//! Best compression
CompressionModeBest= 9,
//! Default compression
CompressionModeDefault = -1
};
/*! \brief Strategy
The strategy parameter is used to tune the compression algorithm. Use the
value #StrategyDefault for normal data, #StrategyFiltered for data produced by a
filter (or predictor), or #StrategyHuffmanOnly to force Huffman encoding only (no
string match).
Filtered data consists mostly of small values with a
somewhat random distribution. In this case, the compression algorithm is
tuned to compress them better. The effect of #StrategyFiltered is to force more
Huffman coding and less string matching; it is somewhat intermediate
between #StrategyDefault and #StrategyHuffmanOnly.
The strategy parameter only affects
the compression ratio but not the correctness of the compressed output even
if it is not set appropriately.
*/
static enum EStrategy
{
//! Default
StrategyDefault,
//! filtered data
StrategyFiltered=1,
//! Huffman codes only
StrategyHuffmanOnly=2
};
//! Flush modes
static enum EFlushMode
{
FlushModeNoFlush= 0,
FlushModeSync = 2,
FlushModeFull= 3,
FlushModeFinish = 4
};
//! Default constructor, no arguments
CZipper();
virtual ~CZipper();
//! returns zlib version
static LPCWSTR GetVersion() { return m_stsVersion;};
/*! \brief Sets compression level
\param eCompression compression level
\sa ECompressionMode
*/
void SetCompression( ECompressionMode eCompression) { m_eCompressionMode = eCompression; UpdateParams();};
/*! \brief returns compression
\sa SetCompression
*/
ECompressionMode GetCompression() const { return m_eCompressionMode;};
/*! \brief Sets the strategy
\sa EStrategy
*/
void SetStrategy( EStrategy eStrategy) { m_eStrategy = eStrategy; UpdateParams();};
/*! \brief Returns the compression strategy
*/
EStrategy GetStrategy() const { return m_eStrategy;};
/*! \brief Start zip/unzip process
\param eArchiveMode archive mode, see #EOpenMode
\return true if file opened succesfully, false otherwize
#Open can be used to read a file which is not in gzip format; in this
#ReadBuffer and #ReadBufferSize will directly read from the file without decompression.
*/
virtual bool Open(EArchiveMode eArchiveMode);
/*! \brief Closes the file
\return true if succesful, false otherwize
If writing, flushes the pending writing operator and closes the file.
*/
virtual bool Close()=0;
//! returns true if file is currently opened
virtual bool IsOpen() const=0;
//! returns true if zip is in write mode
bool IsWriting() const { return m_eArchiveMode == ArchiveModeWrite;};
//! returns true if zip is in read mode
bool IsReading() const { return m_eArchiveMode == ArchiveModeRead;};
/*! \brief Writes buffer to zip file
\param pBuffer memory buffer
\param nBytes size in bytes of pBuffer
\return true if writing succesful
*/
virtual bool WriteBuffer( voidp pBuffer, size_t nBytes)=0;
/*! \brief Writes const string to zip file
\param str the string to zip
\return true if writing succesful
*/
virtual bool WriteString( LPCWSTR str)=0;
/*! \brief Reads buffer
\param pBuffer pointer to memory buffer of size nBytes
\param nBytes size of the memory buffer
\return number of bytes filled in memory buffer
*/
virtual int ReadBufferSize( voidp pBuffer, size_t nBytes)=0;
/*! \brief Reads buffer
\param ppBuffer pointer to pointer where new memory buffer will be stored
\param nBytes size of new memory buffer in bytes
*/
virtual int ReadBuffer( voidp* ppBuffer, size_t& nBytes)=0;
protected:
//! Update compression and strategy parameters (only in write mode)
virtual void UpdateParams()=0;
//! Archive opening mode
EArchiveMode m_eArchiveMode;
//! compression level
ECompressionMode m_eCompressionMode;
//! strategy
EStrategy m_eStrategy;
//! ZLib version string
static LPCWSTR m_stsVersion;
};
/*! \brief GZip class (minimal class wrapper for the zlib methods)
\author Jonathan de Halleux, dehalleux@pelikhan.com, 2002
\par Description
This documents present CGZip, C++ class wrapper for the gzip methods, which are included in the zlib libary.
The intention of this class is to have a <b>simple</b> class for zipping-unzipping buffers.
The main features of the class are:
- Compress, decompress LPCWSTR to file,
- Compress, decompress memory buffer to file,
- Non-MFC,
- Hides zlib so you don't have to distribute the zlib headers,
- UNICODE compliant,
\par Examples
In the following examples, we shall consider:
\code
// CGZip is in the zlib namespace
using namespace zlib;
CGZip gzip;
\endcode
<em>Zipping a memory buffer or a string</em>
First of all, let's open a file for writing:
\code
if(!gzip.Open(_T("myFile.gz"), CGZip::ArchiveModeWrite)))
{
// the file could not be opened...
}
\endcode
As you can see, Open returns true if success and false otherwize. All the methods (almost) have this behavior.
Now we can send data and strings to the file:
- Strings:
\code
LPCWSTR szString = _T("This is a test string\n");
// writing string
gzip.WriteString(szString);
\endcode
- Buffers:
\code
void* pBuffer; // a memory buffer
int len; // size in bytes of the memory buffer
// writing buffer
gzip.WriteBuffer(pBuffer,len);
\endcode
When done, you must close the file:
\code
gzip.Close();
\endcode
Note that if gzip goes out of scope, it is automatically closed.
<em>Unzipping a buffer or a string</em>
The reading behaves pretty much like the writing: First of all, open a file for reading:
\code
if(!gzip.Open(_T("myFile.gz"), CGZip::ArchiveModeRead)))
{
// the file could not be opened...
}
\endcode
Now, you can read a buffer with fixed length or the hole file:
- a string
LPTSTR szString;
gzip.ReadString(&szString);
- the hole file
\code
void* pBuffer=NULL;
int len;
// reads and unzip the hole file, len contains the resulting size of pBuffer
gzip.ReadBuffer(&pBuffer,&len);
\endcode
- a fixed length buffer:
\code
int len;
char* pBuffer[len];
// reads and unzip the hole file, len contains the resulting size of pBuffer
gzip.ReadBufferSize(pBuffer,len);
\endcode
\par GZip license
This piece of code is totally, uterly free for commercial and non-commercial use. Howerver, it uses
zlib so you should check the zlib license before using it:
\par ZLib license
This class uses zlib.
The 'zlib' compression library provides in-memory compression and
decompression functions, including integrity checks of the uncompressed
data. This version of the library supports only one compression method
(deflation) but other algorithms will be added later and will have the same
stream interface.
Compression can be done in a single step if the buffers are large
enough (for example if an input file is mmap'ed), or can be done by
repeated calls of the compression function. In the latter case, the
application must provide more input and/or consume the output
(providing more output space) before each call.
The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio.
The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never
crash even in case of corrupted input.
\code
zlib.h -- interface of the 'zlib' general purpose compression library
version 1.1.4, March 11th, 2002
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
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.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
\endcode
*/
class CGZip : public CZipper
{
public:
CGZip():m_gzf(NULL),m_bufferSize(0){};
virtual ~CGZip();
/*! \brief Open a file
\param szFileName name of the file to open
\param eArchiveMode archive mode, see #EOpenMode
\return true if file opened succesfully, false otherwize
#Open can be used to read a file which is not in gzip format; in this
#ReadBuffer and #ReadBufferSize will directly read from the file without decompression.
*/
bool Open(LPCWSTR szFileName, EArchiveMode eArchiveMode);
/*! \brief Closes the file
\return true if succesful, false otherwize
If writing, flushes the pending writing operator and closes the file.
*/
virtual bool Close();
/*! brief Flushes all pending output into the compressed file.
\param eFlush See EFlushMode
\return true if succesful, false otherwize
#Flush should be called only when strictly necessary because it can
degrade compression.
*/
bool Flush( EFlushMode eFlush);
//! returns true if file is currently opened
virtual bool IsOpen() const { return m_gzf != NULL;};
//! returns true if end of file has been reached
bool IsEOF() const;
/*! \brief Writes buffer to zip file
\param pBuffer memory buffer
\param nBytes size in bytes of pBuffer
\return true if writing succesful
*/
bool WriteBuffer( voidp pBuffer, size_t nBytes);
/*! \brief Writes const string to zip file
\param str the string to zip
\return true if writing succesful
*/
bool WriteString( LPCWSTR str);
/*! \brief Reads buffer
\param pBuffer pointer to memory buffer of size nBytes
\param nBytes size of the memory buffer
\return number of bytes filled in memory buffer
*/
int ReadBufferSize( voidp pBuffer, size_t nBytes);
/*! \brief Reads buffer
\param ppBuffer pointer to pointer where new memory buffer will be stored
\param nBytes size of new memory buffer in bytes
*/
int ReadBuffer( voidp* ppBuffer, size_t& nBytes);
/*! \brief Reads String
\param ppString pointer to pointer where new memory buffer will be stored
*/
int ReadString( LPWSTR* ppString);
protected:
//! Update compression and strategy parameters (only in write mode)
void UpdateParams();
//! zip file handle
voidp m_gzf;
size_t m_bufferSize;
};
};

View File

@@ -0,0 +1,623 @@
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
This code is largely copied from inflate.c. Normally either infback.o or
inflate.o would be linked into an application--not both. The interface
with inffast.c is retained so that optimized assembler-coded versions of
inflate_fast() can be used with either inflate.c or infback.c.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* function prototypes */
local void fixedtables OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
Z_NULL to use the library memory allocation functions.
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_streamp strm;
int windowBits;
unsigned char FAR *window;
const char *version;
int stream_size;
{
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL || window == Z_NULL ||
windowBits < 8 || windowBits > 15)
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
}
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->dmax = 32768U;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
state->write = 0;
state->whave = 0;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */
#define PULL() \
do { \
if (have == 0) { \
have = in(in_desc, &next); \
if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */
#define PULLBYTE() \
do { \
PULL(); \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflateBack() with
an error. */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window
if it's full. If the write fails, return from inflateBack() with a
Z_BUF_ERROR. */
#define ROOM() \
do { \
if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \
if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/*
strm provides the memory allocation functions and window buffer on input,
and provides information on the unused input on return. For Z_DATA_ERROR
returns, strm will also provide an error message.
in() and out() are the call-back input and output functions. When
inflateBack() needs more input, it calls in(). When inflateBack() has
filled the window with output, or when it completes with data in the
window, it calls out() to write out the data. The application must not
change the provided input until in() is called again or inflateBack()
returns. The application must not change the window/output buffer until
inflateBack() returns.
in() and out() are called with a descriptor parameter provided in the
inflateBack() call. This parameter can be a structure that provides the
information required to do the read or write, as well as accumulated
information on the input and output such as totals and check values.
in() should return zero on failure. out() should return non-zero on
failure. If either in() or out() fails, than inflateBack() returns a
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
was in() or out() that caused in the error. Otherwise, inflateBack()
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
error, or Z_MEM_ERROR if it could not allocate memory for the state.
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_streamp strm;
in_func in;
void FAR *in_desc;
out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code this; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */
if (strm == Z_NULL || strm->state == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* Inflate until end of block marked as last */
for (;;)
switch (state->mode) {
case TYPE:
/* determine and dispatch block type */
if (state->last) {
BYTEBITS();
state->mode = DONE;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
/* get and verify stored block length */
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
/* copy stored block from input to output */
while (state->length != 0) {
copy = state->length;
PULL();
ROOM();
if (copy > have) copy = have;
if (copy > left) copy = left;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
/* get dynamic table entries descriptor */
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */
state->have = 0;
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
/* get length and distance code code lengths */
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.val < 16) {
NEEDBITS(this.bits);
DROPBITS(this.bits);
state->lens[state->have++] = this.val;
}
else {
if (this.val == 16) {
NEEDBITS(this.bits + 2);
DROPBITS(this.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (this.val == 17) {
NEEDBITS(this.bits + 3);
DROPBITS(this.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(this.bits + 7);
DROPBITS(this.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* handle error breaks in while */
if (state->mode == BAD) break;
/* build code tables */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN;
case LEN:
/* use inflate_fast() if we have enough input and output */
if (have >= 6 && left >= 258) {
RESTORE();
if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD();
break;
}
/* get a literal, length, or end-of-block code */
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.op && (this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
state->length = (unsigned)this.val;
/* process literal */
if (this.op == 0) {
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
}
/* process end of block */
if (this.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
if (this.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */
for (;;) {
this = state->distcode[BITS(state->distbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if ((this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
if (this.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)this.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */
do {
ROOM();
copy = state->wsize - state->offset;
if (copy < left) {
from = put + copy;
copy = left - copy;
}
else {
from = put - state->offset;
copy = left;
}
if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy;
do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0);
break;
case DONE:
/* inflate stream terminated properly -- write leftover output */
ret = Z_STREAM_END;
if (left < state->wsize) {
if (out(out_desc, state->window, state->wsize - left))
ret = Z_BUF_ERROR;
}
goto inf_leave;
case BAD:
ret = Z_DATA_ERROR;
goto inf_leave;
default: /* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR;
goto inf_leave;
}
/* Return unused input */
inf_leave:
strm->next_in = next;
strm->avail_in = have;
return ret;
}
int ZEXPORT inflateBackEnd(strm)
z_streamp strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}

View File

@@ -0,0 +1,318 @@
/* inffast.c -- fast decoding
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifndef ASMINF
/* Allow machine dependent optimization for post-increment or pre-increment.
Based on testing to date,
Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- M68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define OFF 1
# define PUP(a) *++(a)
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
unsigned char FAR *in; /* local strm->next_in */
unsigned char FAR *last; /* while in < last, enough input available */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code this; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
unsigned dist; /* match distance */
unsigned char FAR *from; /* where to copy match from */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
this = lcode[hold & lmask];
dolen:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
if (op == 0) { /* literal */
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
PUP(out) = (unsigned char)(this.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
this = dcode[hold & dmask];
dodist:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
if (op & 16) { /* distance base */
dist = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
from = window - OFF;
if (write == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += write - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
this = dcode[this.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
this = lcode[this.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
}
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */

View File

@@ -0,0 +1,11 @@
/* inffast.h -- header to use inffast.c
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
void inflate_fast OF((z_streamp strm, unsigned start));

View File

@@ -0,0 +1,94 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by makefixed().
*/
/* WARNING: this file should *not* be used by applications. It
is part of the implementation of the compression library and
is subject to change. Applications should only use zlib.h.
*/
static const code lenfix[512] = {
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{0,9,255}
};
static const code distfix[32] = {
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{22,5,193},{64,5,0}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN, /* i: waiting for length/lit code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to the BAD or MEM mode -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
NAME -> COMMENT -> HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
Read deflate blocks:
TYPE -> STORED or TABLE or LEN or CHECK
STORED -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN
Read deflate codes:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 7K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
};

View File

@@ -0,0 +1,329 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#define MAXBITS 15
const char inflate_copyright[] =
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
/*
Build a set of tables to decode the provided canonical Huffman code.
The code lengths are lens[0..codes-1]. The result starts at *table,
whose indices are 0..2^bits-1. work is a writable array of at least
lens shorts, which is used as a work area. type is the type of code
to be generated, CODES, LENS, or DISTS. On return, zero is success,
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
on return points to the next available entry's address. bits is the
requested root table index bits, and on return it is the actual root
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
int inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
code FAR * FAR *table;
unsigned FAR *bits;
unsigned short FAR *work;
{
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */
unsigned min, max; /* minimum and maximum code lengths */
unsigned root; /* number of index bits for root table */
unsigned curr; /* number of index bits for current table */
unsigned drop; /* code bits to drop for sub-table */
int left; /* number of prefix codes available */
unsigned used; /* code entries in table used */
unsigned huff; /* Huffman code */
unsigned incr; /* for incrementing code, index */
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
code this; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
int end; /* use base and extra for symbol > end */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577, 0, 0};
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
28, 28, 29, 29, 64, 64};
/*
Process a set of code lengths to create a canonical Huffman code. The
code lengths are lens[0..codes-1]. Each length corresponds to the
symbols 0..codes-1. The Huffman code is generated by first sorting the
symbols by length from short to long, and retaining the symbol order
for codes with equal lengths. Then the code starts with all zero bits
for the first code of the shortest length, and the codes are integer
increments for the same length, and zeros are appended as the length
increases. For the deflate format, these bits are stored backwards
from their more natural integer increment ordering, and so when the
decoding tables are built in the large loop below, the integer codes
are incremented backwards.
This routine assumes, but does not check, that all of the entries in
lens[] are in the range 0..MAXBITS. The caller must assure this.
1..MAXBITS is interpreted as that code length. zero means that that
symbol does not occur in this code.
The codes are sorted by computing a count of codes for each length,
creating from that a table of starting indices for each length in the
sorted table, and then entering the symbols in order in the sorted
table. The sorted table is work[], with that space being provided by
the caller.
The length counts are used for other purposes as well, i.e. finding
the minimum and maximum length codes, determining if there are any
codes at all, checking for a valid set of lengths, and looking ahead
at length counts to determine sub-table sizes when building the
decoding tables.
*/
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
for (len = 0; len <= MAXBITS; len++)
count[len] = 0;
for (sym = 0; sym < codes; sym++)
count[lens[sym]]++;
/* bound code lengths, force root to be within code lengths */
root = *bits;
for (max = MAXBITS; max >= 1; max--)
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) { /* no symbols to code at all */
this.op = (unsigned char)64; /* invalid code marker */
this.bits = (unsigned char)1;
this.val = (unsigned short)0;
*(*table)++ = this; /* make a table to force an error */
*(*table)++ = this;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
for (min = 1; min <= MAXBITS; min++)
if (count[min] != 0) break;
if (root < min) root = min;
/* check for an over-subscribed or incomplete set of lengths */
left = 1;
for (len = 1; len <= MAXBITS; len++) {
left <<= 1;
left -= count[len];
if (left < 0) return -1; /* over-subscribed */
}
if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + count[len];
/* sort symbols by length, by symbol order within each length */
for (sym = 0; sym < codes; sym++)
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
/*
Create and fill in decoding tables. In this loop, the table being
filled is at next and has curr index bits. The code being used is huff
with length len. That code is converted to an index by dropping drop
bits off of the bottom. For codes where len is less than drop + curr,
those top drop + curr - len bits are incremented through all values to
fill the table with replicated entries.
root is the number of index bits for the root table. When len exceeds
root, sub-tables are created pointed to by the root entry with an index
of the low root bits of huff. This is saved in low to check for when a
new sub-table should be started. drop is zero when the root table is
being filled, and drop is root when sub-tables are being filled.
When a new sub-table is needed, it is necessary to look ahead in the
code lengths to determine what size sub-table is needed. The length
counts are used for this, and so count[] is decremented as codes are
entered in the tables.
used keeps track of how many table entries have been allocated from the
provided *table space. It is checked when a LENS table is being made
against the space in *table, ENOUGH, minus the maximum space needed by
the worst case distance code, MAXD. This should never happen, but the
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
This assumes that when type == LENS, bits == 9.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
routine permits incomplete codes, so another loop after this one fills
in the rest of the decoding tables with invalid code markers.
*/
/* set up for code type */
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
end = 19;
break;
case LENS:
base = lbase;
base -= 257;
extra = lext;
extra -= 257;
end = 256;
break;
default: /* DISTS */
base = dbase;
extra = dext;
end = -1;
}
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* check available table space */
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
this.bits = (unsigned char)(len - drop);
if ((int)(work[sym]) < end) {
this.op = (unsigned char)0;
this.val = work[sym];
}
else if ((int)(work[sym]) > end) {
this.op = (unsigned char)(extra[work[sym]]);
this.val = base[work[sym]];
}
else {
this.op = (unsigned char)(32 + 64); /* end of block */
this.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
min = fill; /* save offset to next table */
do {
fill -= incr;
next[(huff >> drop) + fill] = this;
} while (fill != 0);
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
/* go to next symbol, update count, len */
sym++;
if (--(count[len]) == 0) {
if (len == max) break;
len = lens[work[sym]];
}
/* create new sub-table if needed */
if (len > root && (huff & mask) != low) {
/* if first time, transition to sub-tables */
if (drop == 0)
drop = root;
/* increment past last table */
next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
left = (int)(1 << curr);
while (curr + drop < max) {
left -= count[curr + drop];
if (left <= 0) break;
curr++;
left <<= 1;
}
/* check for enough space */
used += 1U << curr;
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsigned char)curr;
(*table)[low].bits = (unsigned char)root;
(*table)[low].val = (unsigned short)(next - *table);
}
}
/*
Fill in rest of table for incomplete codes. This loop is similar to the
loop above in incrementing huff for table indices. It is assumed that
len is equal to curr + drop, so there is no loop needed to increment
through high index bits. When the current sub-table is filled, the loop
drops back to the root table to fill in any remaining entries there.
*/
this.op = (unsigned char)64; /* invalid code marker */
this.bits = (unsigned char)(len - drop);
this.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
this.bits = (unsigned char)len;
}
/* put invalid code marker in table */
next[huff >> drop] = this;
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
}
/* set return parameters */
*table += used;
*bits = root;
return 0;
}

View File

@@ -0,0 +1,55 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
/* op values as set by inflate_table():
00000000 - literal
0000tttt - table link, tttt != 0 is the number of table index bits
0001eeee - length or distance, eeee is the number of extra bits
01100000 - end of block
01000000 - invalid code
*/
/* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1444 code structures (852 for length/literals
and 592 for distances, the latter actually the result of an
exhaustive search). The true maximum is not known, but the value
below is more than safe. */
#define ENOUGH 2048
#define MAXD 592
/* Type of code to build for inftable() */
typedef enum {
CODES,
LENS,
DISTS
} codetype;
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
/* header created automatically with -DGEN_TREES_H */
local const ct_data static_ltree[L_CODES+2] = {
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
};
local const ct_data static_dtree[D_CODES] = {
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
};
const uch _dist_code[DIST_CODE_LEN] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
};
local const int base_length[LENGTH_CODES] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 80, 96, 112, 128, 160, 192, 224, 0
};
local const int base_dist[D_CODES] = {
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};

View File

@@ -0,0 +1,61 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h"
/* ===========================================================================
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit(&stream);
if (err != Z_OK) return err;
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
}
*destLen = stream.total_out;
err = inflateEnd(&stream);
return err;
}

View File

@@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

View File

@@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,318 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zutil.h"
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */
#endif
const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */
"file error", /* Z_ERRNO (-1) */
"stream error", /* Z_STREAM_ERROR (-2) */
"data error", /* Z_DATA_ERROR (-3) */
"insufficient memory", /* Z_MEM_ERROR (-4) */
"buffer error", /* Z_BUF_ERROR (-5) */
"incompatible version",/* Z_VERSION_ERROR (-6) */
""};
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
flags = 0;
switch (sizeof(uInt)) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
switch (sizeof(uLong)) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
switch (sizeof(voidpf)) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
switch (sizeof(z_off_t)) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
#ifdef DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
flags += 1 << 9;
#endif
#ifdef ZLIB_WINAPI
flags += 1 << 10;
#endif
#ifdef BUILDFIXED
flags += 1 << 12;
#endif
#ifdef DYNAMIC_CRC_TABLE
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
flags += 1L << 16;
#endif
#ifdef NO_GZIP
flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
flags += 1L << 20;
#endif
#ifdef FASTEST
flags += 1L << 21;
#endif
#ifdef STDC
# ifdef NO_vsnprintf
flags += 1L << 25;
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
#else
flags += 1L << 24;
# ifdef NO_snprintf
flags += 1L << 25;
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
#ifdef DEBUG
# ifndef verbose
# define verbose 0
# endif
int z_verbose = verbose;
void z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
exit(1);
}
#endif
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
#if defined(_WIN32_WCE)
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
*/
int errno = 0;
#endif
#ifndef HAVE_MEMCPY
void zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
}
int zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void zmemzero(dest, len)
Bytef* dest;
uInt len;
{
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
}
#endif
#ifdef SYS16BIT
#ifdef __TURBOC__
/* Turbo C in 16-bit mode */
# define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with an offset of 8, so we
* must fix the pointer. Warning: the pointer must be put back to its
* original form in order to free it, use zcfree().
*/
#define MAX_PTR 10
/* 10*64K = 640K */
local int next_ptr = 0;
typedef struct ptr_table_s {
voidpf org_ptr;
voidpf new_ptr;
} ptr_table;
local ptr_table table[MAX_PTR];
/* This table is used to remember the original form of pointers
* to large buffers (64K). Such pointers are normalized with a zero offset.
* Since MSDOS is not a preemptive multitasking OS, this table is not
* protected from concurrent access. This hack doesn't work anyway on
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size;
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf;
} else {
buf = farmalloc(bsize + 16L);
}
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
table[next_ptr].org_ptr = buf;
/* Normalize the pointer to seg:0 */
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
*(ush*)&buf = 0;
table[next_ptr++].new_ptr = buf;
return buf;
}
void zcfree (voidpf opaque, voidpf ptr)
{
int n;
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
}
/* Find the original pointer */
for (n = 0; n < next_ptr; n++) {
if (ptr != table[n].new_ptr) continue;
farfree(table[n].org_ptr);
while (++n < next_ptr) {
table[n-1] = table[n];
}
next_ptr--;
return;
}
ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found");
}
#endif /* __TURBOC__ */
#ifdef M_I86
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
# define _halloc halloc
# define _hfree hfree
#endif
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
if (opaque) opaque = 0; /* to make compiler happy */
return _halloc((long)items, size);
}
void zcfree (voidpf opaque, voidpf ptr)
{
if (opaque) opaque = 0; /* to make compiler happy */
_hfree(ptr);
}
#endif /* M_I86 */
#endif /* SYS16BIT */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
if (opaque) items += size - size; /* make compiler happy */
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
(voidpf)calloc(items, size);
}
void zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
free(ptr);
if (opaque) return; /* make compiler happy */
}
#endif /* MY_ZCALLOC */

View File

@@ -0,0 +1,269 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
#define ZLIB_INTERNAL
#include "zlib.h"
#ifdef STDC
# ifndef _WIN32_WCE
# include <stddef.h>
# endif
# include <string.h>
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
# ifdef _WIN32_WCE
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used. We rename it to
* avoid conflict with other libraries that use the same workaround.
*/
# define errno z_errno
# endif
extern int errno;
#else
# ifndef _WIN32_WCE
# include <errno.h>
# endif
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
typedef unsigned char uch;
typedef uch FAR uchf;
typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = (char*)ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
#ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS
#endif
/* default windowBits for decompression. MAX_WBITS is for compression only */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default memLevel */
#define STORED_BLOCK 0
#define STATIC_TREES 1
#define DYN_TREES 2
/* The three kinds of block type */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__)
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
#endif
#ifdef AMIGA
# define OS_CODE 0x01
#endif
#if defined(VAXC) || defined(VMS)
# define OS_CODE 0x02
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
#if defined(ATARI) || defined(atarist)
# define OS_CODE 0x05
#endif
#ifdef OS2
# define OS_CODE 0x06
# ifdef M_I86
#include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fdopen */
# else
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif
#endif
#ifdef TOPS20
# define OS_CODE 0x0a
#endif
#ifdef WIN32
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
# define OS_CODE 0x0b
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0f
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER > 600))
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif
/* common defaults */
#ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */
#endif
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#if defined(__CYGWIN__)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#ifndef HAVE_VSNPRINTF
# ifdef MSDOS
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
but for now we just assume it doesn't. */
# define NO_vsnprintf
# endif
# ifdef __TURBOC__
# define NO_vsnprintf
# endif
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
# define vsnprintf _vsnprintf
# endif
# endif
# ifdef __SASC
# define NO_vsnprintf
# endif
#endif
#ifdef VMS
# define NO_vsnprintf
#endif
#if defined(pyr)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* Use our own functions for small and medium model with MSC <= 5.0.
* You may have to use the same strategy for Borland C (untested).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
# define HAVE_MEMCPY
#endif
#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len)
# else
# define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
extern void zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef DEBUG
# include <stdio.h>
extern int z_verbose;
extern void z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
void zcfree OF((voidpf opaque, voidpf ptr));
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
#endif /* ZUTIL_H */

View File

@@ -0,0 +1,261 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "NFNet.h"
#include "NFIOBuffer.h"
namespace NaveNet {
NFIOBuffer::NFIOBuffer() : m_iHead(0), m_iTail(0), m_iBufSize(0), m_cBuf(0), m_iBuffered(0)
{
}
NFIOBuffer::~NFIOBuffer()
{
DeleteIOBuf();
}
VOID NFIOBuffer::InitIOBuf()
{
m_iHead = m_iTail = 0;
m_iBuffered = 0;
if(m_cBuf)
memset(m_cBuf, 0, sizeof(m_cBuf));
}
VOID NFIOBuffer::NewIOBuf(INT BufSize)
{
if(BufSize <= 0)
BufSize = IOBUF_DEF_SIZE;
m_cBuf = new CHAR[BufSize];
if(m_cBuf == NULL)
{
// throw "NFIOBuffer::NewIOBuf : Memory allocation failure!";
return;
}
m_iBufSize = BufSize;
InitIOBuf();
}
VOID NFIOBuffer::DeleteIOBuf()
{
if(m_cBuf)
{
delete []m_cBuf;
m_cBuf = NULL;
}
m_iBufSize = 0;
m_iHead = m_iTail = 0;
m_iBuffered = 0;
}
// Size 만큼 Buffer의 내용을 쓴다.
INT NFIOBuffer::Append(const CHAR* Buffer, INT Size)
{
// 오버플로우가 된다.
if(m_iBuffered + Size >= m_iBufSize)
{
// throw "NFIOBuffer::Append : Buffer overflow";
return -1;
}
INT aSize = 0;
INT Added = 0;
// 모든 Size를 추가할때까지 처리한다.
while(Size > 0)
{
if(Size > m_iBufSize-m_iTail)
aSize = m_iBufSize-m_iTail;
else aSize = Size;
if(aSize)
{
memcpy(m_cBuf+m_iTail, Buffer, aSize);
Added += aSize;
Size -= aSize;
Buffer += aSize;
m_iTail += aSize;
if(m_iTail >= m_iBufSize)
m_iTail -= m_iBufSize;
}
}
CalcBuffered();
return Added;
}
// Size만큼 데이타를 읽어 Buffer에 쓴다.
INT NFIOBuffer::GetData(CHAR* Buffer, INT Size)
{
// 써있는 데이타 보다 많이 읽으면 써있는 데이타만 읽게 한다.
if(GetBufferUsed() < Size)
Size = GetBufferUsed();
if(Size <= 0)
return 0;
// 잘려있으면. 처리한다.
if(m_iHead+Size >= m_iBufSize)
{
// 여기에 지금 버그가 있다.
INT Size1 = m_iBufSize - m_iHead;
memcpy(Buffer, m_cBuf+m_iHead, Size1);
memcpy(Buffer+Size1, m_cBuf, Size-Size1);
}
else // 안잘려 있으면.
{
memcpy(Buffer, m_cBuf+m_iHead, Size);
}
m_iHead += Size;
if(m_iHead >= m_iBufSize)
m_iHead -= m_iBufSize;
CalcBuffered();
return Size;
}
INT NFIOBuffer::CheckData(INT Size)
{
// 써있는 데이타 보다 많이 읽으면 써있는 데이타만 읽게 한다.
if(GetBufferUsed() < Size)
Size = GetBufferUsed();
if(Size <= 0)
return 0;
m_iHead += Size;
if(m_iHead >= m_iBufSize)
m_iHead -= m_iBufSize;
CalcBuffered();
return Size;
}
VOID NFIOBuffer::CalcBuffered()
{
if(m_iHead > m_iTail)
m_iBuffered = m_iBufSize - m_iHead + m_iTail;
else
m_iBuffered = m_iTail-m_iHead;
}
NFPacketIOBuffer::NFPacketIOBuffer() : m_iLockHead(0)
{
// 초기화.
NFIOBuffer::NFIOBuffer();
}
NFPacketIOBuffer::~NFPacketIOBuffer()
{
DeleteIOBuf();
}
VOID NFPacketIOBuffer::Lock()
{
m_iLockHead = GetHead();
}
VOID NFPacketIOBuffer::UnLock()
{
SetHead(m_iLockHead);
}
BOOL NFPacketIOBuffer::CheckPacket()
{
PACKETHEADER header;
INT HeaderSize = sizeof(PACKETHEADER);
// Header
if(GetBufferUsed() < HeaderSize)
{
// 에러가 아니라 데이타가 없는거다.
// throw "NFPacketIOBuffer::GetPacket : IOBuffer Used Memory < P_SIZE";
return FALSE;
}
if(HeaderSize != GetData((CHAR*)&header, HeaderSize))
{
// 헤더를 원래대로 초기화 한다.
// throw "NFPacketIOBuffer::GetPacket : Packet Header Size != P_SIZE";
return FALSE;
}
INT PacketSize = header.Size-HeaderSize;
// 헤더는 제대로 들어갔는데 버퍼가 제대로 들어갔는지 확인한다.
if(GetBufferUsed() < PacketSize)
{
// 헤더를 원래대로 초기화 한다.
// 에러가 아니라 데이타가 없는거다.
// throw "NFPacketIOBuffer::GetPacket : IOBuffer Used Memory < PacketLen";
return FALSE;
}
INT GetSize = CheckData(PacketSize);
if(GetSize != PacketSize)
{
// 헤더를 원래대로 초기화 한다.
// throw "NFPacketIOBuffer::GetPacket : Packet Data Read Faild, PacketSize != GetSize";
return FALSE;
}
return TRUE;
}
INT NFPacketIOBuffer::GetPacket(NFPacket* Packet)
{
INT OldHead = GetHead();
INT HeaderSize = HEADERSIZE;
// Header
if(GetBufferUsed() < HeaderSize)
{
// 에러가 아니라 데이타가 없는거다.
// throw "NFPacketIOBuffer::GetPacket : IOBuffer Used Memory < P_SIZE";
return -1;
}
if(HeaderSize != GetData((CHAR*)&Packet->m_Header, HeaderSize))
{
// 헤더를 원래대로 초기화 한다.
SetHead(OldHead);
// throw "NFPacketIOBuffer::GetPacket : Packet Header Size != P_SIZE";
return -2;
}
INT PacketSize = Packet->m_Header.Size-HeaderSize;
// 헤더는 제대로 들어갔는데 버퍼가 제대로 들어갔는지 확인한다.
if(GetBufferUsed() < PacketSize)
{
// 헤더를 원래대로 초기화 한다.
SetHead(OldHead);
// 에러가 아니라 데이타가 없는거다.
// throw "NFPacketIOBuffer::GetPacket : IOBuffer Used Memory < PacketLen";
return -3;
}
// 아직 데이타가 제대로 처리안됐다.
INT GetSize = GetData(Packet->m_Packet, PacketSize);
if(GetSize != PacketSize)
{
// 헤더를 원래대로 초기화 한다.
SetHead(OldHead);
// throw "NFPacketIOBuffer::GetPacket : Packet Data Read Faild, PacketSize != GetSize";
return -4;
}
// 패킷을 제대로 읽어들였다.
return 1;
}
}

View File

@@ -0,0 +1,182 @@
/**
* @file NFIOBuffer.h
* @brief I/O Buffering, Packet I/O Buffering
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
namespace NaveNet {
#define IOBUF_DEF_SIZE DEF_MAXPACKETSIZE*128 // IOBuffer의 기본크기 패킷 1024개만큼 처리가능
/**
@class
@author 강동명(edith2580@gmail.com)
@date 2009-03-03
@brief
@warning
*/
/**
* @class NFIOBuffer
* @brief I/O Buffering 클래스
* @remarks I/O Buffering 을 위한 클래스. Sock을 이용해 패킷을 주고 받을때 패킷이 \r\n
* 합쳐오거나 분할되어 올때 그 패킷을 관리 및 처리할때 사용된다.(IOBuffer을 \r\n
* 상속받은 PacektIOBuffer 클래스로 처리하게.. \r\n
* \r\n
* 기본적으로 PacketBuffer에 저장되는 스트링(?)의 형식은 다음과 같다. \r\n
* --------------------------------------------------------------------------------------- \r\n
* | 2byte | 2byte | CheckSum(4Byte) | Header.Siz-Headere 만큼의 실제 Packet 용량 Header | \r\n
* --------------------------------------------------------------------------------------- \r\n
* IOBuffer클래스는 위의 패킷을 하나의 배열에 순차적으로 넣어 그 패킷을 \r\n
* 관리한다. 2Byte는 65535까지의 길이를 처리한다. \r\n
* @par
* @author Edith
* @date 2009-04-04
*/
class NFIOBuffer
{
public:
/// NFIOBuffer 생성자
NFIOBuffer();
/// NFIOBuffer 소멸자
virtual ~NFIOBuffer();
public:
/// 사용된 버퍼의 크기 계산.
VOID CalcBuffered();
/**
* @brief 버퍼 포인터를 얻어옵니다.
* @return 버퍼 포인터
*/
inline CHAR* GetBuffer() { return m_cBuf; }
/**
* @brief Head Pos를 설정합니다.
* @param Head Head Pos값
*/
inline VOID SetHead(INT Head) { m_iHead = Head; CalcBuffered(); }
/**
* @brief Head Pos를 가져옵니다.
* @return Head Pos 값
*/
inline INT GetHead() { return m_iHead; }
/**
* @brief Tail Pos를 설정합니다.
* @param Tail Tail Pos값
*/
inline VOID SetTail(INT Tail) { m_iTail = Tail; }
/**
* @brief Tail Pos를 가져옵니다.
* @return Tail Pos 값
*/
inline INT GetTail() { return m_iTail; }
/**
* @brief 버퍼의 전체 크기를 얻어옵니다.
* @return 버퍼의 전체 크기
*/
inline INT GetBufSize() { return m_iBufSize; }
/**
* @brief 사용중인 버퍼의 길이를 얻어옵니다.
* @return 사용중인 버퍼의 길이
*/
inline INT GetBufferUsed() { return m_iBuffered; }
/**
* @brief 비어있는 버퍼의 길이를 얻어옵니다.
* @return 비어있는 버퍼의 길이
*/
inline INT GetEmptyBuffer() { return m_iBufSize - m_iBuffered; }
/**
* @brief 버퍼를 초기화합니다.
*/
VOID InitIOBuf();
/**
* @brief 버퍼를 추가합니다.
* @param Buffer 버퍼
* @param Size 크기
* @return 추가한 길이
*/
INT Append(const CHAR* Buffer, INT Size);
/**
* @brief 버퍼를 읽습니다.
* @param Buffer 버퍼
* @param Size 읽을 크기
* @return 읽어들인 길이
*/
INT GetData(CHAR* Buffer, INT Size);
/**
* @brief 버퍼길이 체크합니다.
* @param Size 체크할 길이
* @return 체크한 길이 성공시 Size값과 동일
*/
INT CheckData(INT Size);
/**
* @brief 버퍼를 생성합니다.
* @param BufSize 생성할 버퍼 크기
*/
VOID NewIOBuf(INT BufSize);
/**
* @brief 버퍼를 삭제합니다.
*/
VOID DeleteIOBuf();
private:
/// 읽을 버퍼의 시작위치.
INT m_iHead;
/// 사용된 버퍼의 끝.
INT m_iTail;
/// 생성한 버퍼의 사이즈
INT m_iBufSize;
/// 생성한 버퍼의 포인터.
CHAR* m_cBuf;
/// 사용된 버퍼의 사이즈 이값이 음수면 Over Flow..
INT m_iBuffered;
};
/**
* @class NFPacketIOBuffer
* @brief Packet I/O Buffering 클래스
* @remarks NFPacket에 자동화 되어있는 클래스 \r\n
* 서버와 클라이언트간 통신에서 사용된다.
* @par
* @author Edith
* @date 2009-04-04
*/
class NFPacketIOBuffer : public NFIOBuffer
{
public:
/// NFPacketIOBuffer 생성자
NFPacketIOBuffer();
/// NFPacketIOBuffer 소멸자
virtual ~NFPacketIOBuffer();
public:
/// 버퍼를 Lock 합니다.
VOID Lock();
/// 버퍼를 UnLock 합니다.
VOID UnLock();
// 한개분량의 패킷을 얻어온다.
INT GetPacket(NFPacket* Packet);
// 패킷체크
BOOL CheckPacket();
private:
/// Lock 과 UnLock에서 사용할 변수
INT m_iLockHead;
};
}

View File

@@ -0,0 +1,49 @@
#include "NFNet.h"
namespace NaveNet {
int SockRemotePort( SOCKET Sock )
{
sockaddr_in servaddr;
int len;
len = sizeof( servaddr );
if ( getpeername( Sock, (struct sockaddr *)&servaddr, (int*)&len ) == -1 )
return -1;
return ntohs( servaddr.sin_port);
}
int SockRemoteIP( SOCKET Sock, unsigned char ip[4] )
{
sockaddr_in addr;
int len;
unsigned char *a;
len = sizeof( addr );
if( -1 == getpeername( Sock, (struct sockaddr *)&addr, (int*)&len ) )
return -1;
a = (unsigned char *)&(addr.sin_addr);
ip[0] = a[0];
ip[1] = a[1];
ip[2] = a[2];
ip[3] = a[3];
return 0;
}
BOOL GetHostIPByDomain(IN_ADDR &Addr, const char *szDomain)
{
PHOSTENT pHost = gethostbyname(szDomain);
if(NULL == pHost)
{
return FALSE;
}
memcpy(&(Addr.S_un.S_addr), pHost->h_addr_list[0], sizeof(IN_ADDR));
return TRUE;
}
}

View File

@@ -0,0 +1,266 @@
/**
* @file NFNet.h
* @brief Network Base 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
/// 거의 사용되지 않는 내용은 Windows 헤더에서 제외합니다.
#define WIN32_LEAN_AND_MEAN
// Windows 헤더 파일입니다.
#include <windows.h>
#include <time.h> // timer
#include <assert.h> // assert
#include <process.h> // Thread
#include <stdio.h> // standard I/O
#include <stdlib.h>
// sock
#include <winsock2.h> // win32 socket
#pragma comment(lib,"ws2_32.lib")
#include <Mswsock.h> // extension socket library
#pragma comment(lib,"mswsock.lib")
#include "mmsystem.h" // 멀티미디어 타이머를 쓰기
#pragma comment(lib,"winmm.lib")
#include "NFPacket.h"
#include "NFSync.h"
namespace NaveNet {
#define MAX_PACKET 256 /// 최대 Packet 생성 개수
#define WM_CONNECT WM_APP + 0x1001 /// CONNECT 메시지
#define WM_RECV_MSG WM_APP + 0x1002 /// RECV 메시지
#define WM_SOCK_CLOSE WM_APP + 0x1003 /// CLOSE 메시지
/**
* @class NFPacketQueue
* @brief Packet Queue 처리용 클래스
* @remarks
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFPacketQueue
{
/// Queue 에서 사용할 INDEX 구조체
struct INDEX
{
/// 다음 인덱스 위치
INDEX* pNext;
/// 패킷
NFPacket Packet;
INDEX()
{
pNext = NULL;
Packet.Init();
}
};
public:
/// NFPacketQueue 생성자
NFPacketQueue()
{
pList = NULL;
pHead = NULL;
pTail = NULL;
nQueueCnt = 0;
nMaxQueueCnt = 0;
}
/// NFPacketQueue 소멸자
~NFPacketQueue()
{
Release();
}
/// Queue를 초기화 합니다.
VOID Release()
{
NFSyncLock Sync(&nfSync);
if(pList)
{
delete [] pList;
pList = NULL;
}
}
/// 패킷 큐를 생성합니다.
BOOL Create(int nMAXCnt = MAX_PACKET)
{
NFSyncLock Sync(&nfSync);
if(nMAXCnt <= 0) return FALSE;
if(pList)
{
delete [] pList;
pList = NULL;
}
nMaxQueueCnt = nMAXCnt;
if((pList = new INDEX[nMaxQueueCnt]) == NULL)
{
nMaxQueueCnt = 0;
return FALSE;
}
for(int i = nMaxQueueCnt - 1; i >= 0 ; i--)
{
if( (i+1) == nMaxQueueCnt)
{
pList[i].pNext = &pList[0];
continue;
}
pList[i].pNext = &pList[i+1];
}
pHead = pTail = &pList[0];
return TRUE;
}
/// 큐의 개수를 얻어옵니다.
int GetQueCnt()
{
NFSyncLock Sync(&nfSync);
return nQueueCnt;
}
/// 큐를 리셋합니다.
void Reset()
{
NFSyncLock Sync(&nfSync);
pHead = pTail = &pList[0];
nQueueCnt = 0;
}
/// 패킷을 추가합니다.
BOOL Add(NFPacket& Packet)
{
NFSyncLock Sync(&nfSync);
if(!pList) return FALSE;
if(nQueueCnt == nMaxQueueCnt)
{
nQueueCnt = 0;
pHead = pTail = &pList[0];
return FALSE;
}
//if(szData[0] == NULL) return FALSE;
if(Packet.m_Header.Size <= 0) return FALSE;
if(Packet.m_Header.Size >= DEF_MAXPACKETSIZE) return FALSE;
// Head의 Size는 Header 사이즈 포함한 사이즈다.
int PacketSize = Packet.m_Header.Size-sizeof(Packet.m_Header);
// 맞춰서 복사..
CopyMemory(&pTail->Packet.m_Header, &Packet.m_Header, sizeof(Packet.m_Header));
CopyMemory(pTail->Packet.m_Packet,Packet.m_Packet,PacketSize);
pTail->Packet.m_Packet[PacketSize] = 0;
pTail = pTail->pNext;
InterlockedIncrement((LONG*)&nQueueCnt);
return TRUE;
}
/**
* @brief 패킷 정보를 얻어옵니다.
* @param Packet 패킷 포인터
* @return 패킷의 사이즈
*/
int GetPnt(NFPacket** Packet)
{
NFSyncLock Sync(&nfSync);
if(!pList) return -1;
if(nQueueCnt == 0) return -1;
int nLen = -1;
*Packet = &pHead->Packet;
nLen = pHead->Packet.m_Header.Size;
return nLen;
}
/// 첫번재 패킷을 삭제합니다.
void Del()
{
NFSyncLock Sync(&nfSync);
if(!pList) return;
if(nQueueCnt == 0) return;
int nLen = -1;
pHead->Packet.Init();
pHead = pHead->pNext;
InterlockedDecrement((LONG*)&nQueueCnt);
}
/**
* @brief 패킷 정보를 얻어옵니다.
* @param Packet 패킷 포인터
* @return 패킷 사이즈
*/
int Get(NFPacket& Packet)
{
NFSyncLock Sync(&nfSync);
if(!pList) return -1;
if(nQueueCnt == 0) return -1;
int nLen = -1;
int PacketSize = pHead->Packet.m_Header.Size-sizeof(pHead->Packet.m_Header);
CopyMemory(&Packet.m_Header, &pHead->Packet.m_Header, sizeof(Packet.m_Header));
CopyMemory(Packet.m_Packet, pHead->Packet.m_Packet, PacketSize);
Packet.m_Packet[PacketSize] = 0;
nLen = Packet.m_Header.Size;
pHead->Packet.Init();
pHead = pHead->pNext;
InterlockedDecrement((LONG*)&nQueueCnt);
return nLen;
}
private:
/// 패킷의 리스트
INDEX* pList;
/// 패킷 리스트의 시작
INDEX* pHead;
/// 패킷 리스트의 끝
INDEX* pTail;
/// 현재 사용되는 큐의 개수
int nQueueCnt;
/// 최대 큐의 개수
int nMaxQueueCnt;
/// 동기화 변수
NFSync nfSync;
};
/// Socket의 Port를얻어온다.
int SockRemotePort( SOCKET Sock );
/// Socket의 IP를얻어온다.
int SockRemoteIP( SOCKET Sock, unsigned char ip[4] );
/// Domain이름으로 ip를 얻어옵니다.
BOOL GetHostIPByDomain(IN_ADDR &Addr, const char *szDomain);
}

View File

@@ -0,0 +1,492 @@
#include "NFNet.h"
#include "NFNetClientS.h"
namespace NaveNet {
NFNetClientS::NFNetClientS() : m_hSocket(NULL), m_nPort(0),
m_hEventThread(NULL), m_hEvent(NULL), m_bConnect(FALSE), m_bClose(FALSE)
{
m_SendQueue.Create(64);
m_RecvQueue.Create(256);
m_RecvIO.NewIOBuf(0); // 0으로 하면 기본적으로 DefaultPacketSize * 1024
ZeroMemory(m_strIPAddr, sizeof(m_strIPAddr)); // Server IP저장
WinSockInit();
}
NFNetClientS::~NFNetClientS()
{
// 다시 커넷을 종료
// m_bConnect = TRUE; // Connect 변수 변경
// CloseAll();
OnClose();
Stop(); // 종료 함수 호출
// 버퍼삭제
m_SendQueue.Release();
m_RecvQueue.Release();
m_RecvIO.DeleteIOBuf();
WSACleanup();
}
BOOL NFNetClientS::WinSockInit()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
WSACleanup();
// Tell the user that we could not find a usable
// WinSock DLL.
return FALSE;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
// Tell the user that we could not find a usable //
// WinSock DLL. //
WSACleanup( );
return FALSE;
}
return TRUE;
}
BOOL NFNetClientS::Init( LPCSTR szIP, int nPort )
{
m_nPort = nPort; // 포트 번호
unsigned long dwThreadId = 0; // 스레드 생성을 위한 변수
// ip 어드레스
IN_ADDR LoginAddress;
if (GetHostIPByDomain(LoginAddress, szIP))
strncpy(m_strIPAddr, inet_ntoa(LoginAddress), 32);
else
strncpy(m_strIPAddr, szIP, 32);
// 연결을 시킨다. 서버로.. 만약 서버연결에 실패한다면
// Netword Event 에서 FW_CLOSE가 발생해 소켓이 Close된다.
if(!Connect())
{
// 실패했을경우 종료한다.
Sleep(100); // Sleep...
OnClose();
//LOG_ERROR((L"ClientCtrl Init Faild."));
return FALSE;
}
m_bClose = FALSE;
m_hEventThread =
(HANDLE)CreateThread(NULL, // Security
0, // Stack size - use default
EventThreadProc, // Thread fn entry point
(void*) this,
0, // Init flag
&dwThreadId); // Thread address
return TRUE;
}
void NFNetClientS::Disconnect()
{
// 이건 무조건 Close해줘야하기 때문에 CloseAll() 호출하지 않고 직접 끈다.
OnClose();
Stop(); // 종료 함수 호출
}
void NFNetClientS::Stop()
{
if (m_hSocket)
{
struct linger li = {0, 0}; // Default: SO_DONTLINGER
li.l_onoff = 1; // SO_LINGER, timeout = 0
shutdown(m_hSocket, SD_BOTH ); // 오잉? 이게 뭐지? ^^;; 담에 찾아보자
// 2001년 9월 6일
// 클로즈 소켓 전에 큐된 데이타를 보낼지 말지 결정하는 옵션
setsockopt(m_hSocket, SOL_SOCKET, SO_LINGER, (CHAR *)&li, sizeof(li));
closesocket(m_hSocket); // 소켓 닫기
m_hSocket = NULL;
}
if(m_hEventThread) CloseHandle(m_hEventThread);
m_hEventThread = NULL;
if(m_hEvent) WSACloseEvent(m_hEvent);
m_hEvent = NULL;
}
void NFNetClientS::CloseAll()
{
if(m_bConnect)
{
OnClose();
Stop(); // 종료 함수 호출
}
}
void NFNetClientS::UpdateQue()
{
while(GetQueCnt() != 0)
{
// 패킷이 전달됐는지 검사.
NFPacket* pPacket = NULL;
int Cnt = GetPacket(&pPacket);
/*
// 사이즈가 0보다 작거나 Packet 가 NULL이면.
if(Cnt <= 0 || pPacket == NULL)
{
//LOG_ERROR((L"NFNetClientS::UpdateQue() Packet Error"));
//assert( "NFNetClientS::UpdateQue() Packet Error.");
}
*/
// 함수 호출
ProcessPacket(pPacket, Cnt);
// 패킷 제거
PopPacket();
}
}
void NFNetClientS::Update()
{
if(!m_bConnect) return;
UpdateQue();
OnSendPacketData();
OnReadPacketData();
}
BOOL NFNetClientS::OnClose()
{
m_bClose = TRUE;
m_bConnect = FALSE; // Connect 변수 변경
// 실제 파일
OnSocketEvent(WM_SOCK_CLOSE, 0);
return FALSE;
}
BOOL NFNetClientS::Connect()
{
// 연결중이라면
if(m_bConnect) return TRUE;
// 소켓이 남아 있다면
Stop();
m_RecvQueue.Reset();
m_SendQueue.Reset();
m_RecvIO.InitIOBuf();
// 소켓 생성
m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 소켓 생성 검사
if (m_hSocket == INVALID_SOCKET)
{
OnSocketEvent(WM_CONNECT, FALSE);
return FALSE;
}
// 네트워크 이벤트 핸들 생성
m_hEvent = WSACreateEvent();
if (m_hEvent == WSA_INVALID_EVENT)
{
Stop();
return FALSE;
}
// Request async notification
int nRet = WSAEventSelect(m_hSocket,
m_hEvent,
FD_CLOSE | FD_CONNECT); // 신호를 선별하여 받게 한다
// 에러라면
if (nRet == SOCKET_ERROR)
{
Stop();
return FALSE;
}
// 비동기 방식
unsigned long ul = 1;
nRet = ioctlsocket(m_hSocket, FIONBIO, (unsigned long*)&ul);
// 소켓 생성 검사
if (m_hSocket == SOCKET_ERROR)
{
OnSocketEvent(WM_CONNECT, FALSE);
return FALSE;
}
/////////////////////////////////
// 소켓의 성능 최적화를 위한 세팅
int zero = 0;
int err = 0;
// Send Buffer에 대한 세팅
if( (err = setsockopt( m_hSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&zero, sizeof(zero))) == SOCKET_ERROR)
{
closesocket(m_hSocket);
m_hSocket = NULL;
return FALSE;
}
// Receive Buffer에 대한 세팅
if((err = setsockopt( m_hSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&zero, sizeof(zero) )) == SOCKET_ERROR)
{
closesocket(m_hSocket);
m_hSocket = NULL;
return FALSE;
}
SOCKADDR_IN saServer;
memset(&saServer,0,sizeof(saServer));
saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(m_strIPAddr);
saServer.sin_port = htons(m_nPort);
// 서버와 Connect
nRet = connect(m_hSocket,(sockaddr*)&saServer, sizeof(saServer));
// 소켓 에러이거나 블럭킹이 되었다면
if (nRet == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
Stop();
return FALSE;
}
/*
이렇게 Connect를 하면 서버는 AccetpEx가 성공하여 ClientSceesion은
Recv대기상태로 들어간다.
소켓 이벤트는 Connect가 성공하면 FD_CONNECT를 발생시킨다.
*/
return TRUE;
}
DWORD WINAPI NFNetClientS::EventThreadProc(LPVOID lParam)
{
// 클래스를 변수로 받음
NFNetClientS* pThis = reinterpret_cast<NFNetClientS*>(lParam);
WSANETWORKEVENTS events; // 네트워크 이벤트 변수
BOOL bThreadRun = TRUE; // 무한 루프 변수
// 스레드 무한 루프
while(bThreadRun)
{
if(pThis->m_bClose)
{
bThreadRun = FALSE;
break;
}
DWORD dwRet;
dwRet = WSAWaitForMultipleEvents(1,
&pThis->m_hEvent,
FALSE,
INFINITE,
FALSE);
if(!pThis->m_hSocket)
{
// 종료
bThreadRun = FALSE;
break;
}
// Figure out what happened
int nRet = WSAEnumNetworkEvents(pThis->m_hSocket,
pThis->m_hEvent,
&events);
// 소켓 에러라면,
if (nRet == SOCKET_ERROR)
{
//LOG_ERROR((L"EventThread : SOCKET_ERROR, %d", WSAGetLastError()) );
bThreadRun = FALSE;
break;
}
///////////////////
// Handle events //
bThreadRun = pThis->NetworkEventHanlder(events.lNetworkEvents);
}
// 이리로 스레드가 종료 되면 Server에 의한 클라이언트 종료!!! <비정상 종료>
// 스레드 초기화는 위에서 해주기 때문에 여기서 하지는 않는다.
// pThis->CloseAll();
return 0;
}
VOID NFNetClientS::OnSendPacketData()
{
//////////////////////////////////////////////////////////////////////////////
// Send
int rc = 0;
int idx = 0,size = 0;
CHAR* send_temp=NULL;
NFPacket Packet;
if((size = m_SendQueue.Get(Packet)) != -1)
{
// 여기서 암호화 까지 같이 진행 ??
// 보내기 직전 체크섬을 생성.
size = Packet.EncryptPacket();
send_temp = (CHAR*)&Packet;
while(size > 0)
{
// 10004 : WSACancelBlockingCall를 호출하여 차단 작업이 중단되었습니다.
// 10058 : 해당 소켓이 종료되었으므로 데이터 보내거나 받을 수 없습니다.
// 10038 : 연결이 끊어진 소켓을 사용할려고 할때 난다.
if((rc = send(m_hSocket, &send_temp[idx], size, 0)) == SOCKET_ERROR)
{
// 블럭킹 에러라면
if (GetLastError() != WSAEWOULDBLOCK) // 블럭킹 에러가 아니라면
{
//LOG_ERROR((L"SendThread : SOCKET_ERROR, %d", WSAGetLastError()));
break;
}
}
else
{
// 에러가 없다면
size -= rc;
idx += rc;
}
}
idx = 0;
size = 0;
}
//////////////////////////////////////////////////////////////////////////////
}
VOID NFNetClientS::OnReadPacketData()
{
//////////////////////////////////////////////////////////////////////////////
// Recv
int Ret = recv(m_hSocket, m_RecvBuffer, DEF_MAXPACKETSIZE, 0); // 데이타 Receive
if(Ret == 0) // Graceful close
{
CloseAll();
return;
}
else if (Ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK ) // 블럭킹 에러가 아니라면
{
//LOG_ERROR((L"[Recv] Packet Size Error : SOCKET_ERROR, %d", WSAGetLastError()));
CloseAll();
return;
}
if(m_RecvIO.Append(m_RecvBuffer, Ret) == -1)
{
//LOG_ERROR((L"m_RecvIO.Append : Buffer Overflow..") );
}
// 받은 패킷은 IOBuffer에 넣어 처리한다.
if(m_RecvIO.GetPacket(&m_RecvPacket) == 1)
{
m_RecvPacket.DecryptPacket();
if(m_RecvPacket.IsAliveChecksum())
{
// 여기서 한패킷 처리 루틴 호출
m_RecvQueue.Add(m_RecvPacket);
// Message Type 일때 이걸로 보낸다.
// 만약 Update 이벤트 호출이면 이 루틴을 주석처리 해준다.
OnSocketEvent(WM_RECV_MSG, m_RecvPacket.m_Header.Size);
}
m_RecvPacket.Init();
}
}
BOOL NFNetClientS::NetworkEventHanlder(LONG lEvent)
{
BOOL bFlag = TRUE;
// if(lEvent & FD_READ)
// {
// bFlag = OnReadPacketData();
// }
if(lEvent & FD_CLOSE)
{
bFlag = FALSE;
}
if(lEvent & FD_CONNECT)
{
bFlag = OnConnect();
}
return bFlag;
}
BOOL NFNetClientS::OnConnect()
{
//////////////////////////////////////////////////////////
// IOCP 활성
//////////////////////////////////////////////////////////
int ErrorCode = send(m_hSocket, (const char*)CONNECT_CHECK_DATA,CONNECT_CHECK_SIZE,0);
if(ErrorCode == SOCKET_ERROR)
{
m_bConnect = FALSE; // 연결 변수 설정 OFF
}
else
{
m_bConnect = TRUE; // 연결 변수 설정 ON
}
OnSocketEvent(WM_CONNECT, m_bConnect);
return m_bConnect;
}
int NFNetClientS::GetQueCnt()
{
return m_RecvQueue.GetQueCnt();
}
int NFNetClientS::GetPacket(NFPacket** Packet)
{
return m_RecvQueue.GetPnt(Packet);
}
void NFNetClientS::PopPacket()
{
m_RecvQueue.Del();
}
BOOL NFNetClientS::SendPost(NFPacket& Packet)
{
// 서버로 Send 하기..
return m_SendQueue.Add(Packet);
}
void NFNetClientS::GetLocalIP(CHAR* LocalIP)
{
CHAR name[256];
CHAR* TempIp;
PHOSTENT hostinfo;
WinSockInit();
if( gethostname ( name, sizeof(name)) == 0)
{
if((hostinfo = gethostbyname(name)) != NULL)
{
TempIp = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
strcpy(LocalIP, TempIp);
}
}
}
}

View File

@@ -0,0 +1,137 @@
/**
* @file NFNetClientS.h
* @brief Network Client 싱글스레드 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include "NFSync.h"
#include "NFIOBuffer.h"
namespace NaveNet {
/**
* @class NFNetClientS
* @brief 클라이언트에서 서버로 접속하기 위한 Network객체 \r\n
* 싱글 스레드용으로 제작된 클래스로 Update에서 패킷Recv,Send처리\r\n
* MainLoop에서 Update함수 호출시 패킷큐가 갱신됨 \r\n
* @remarks
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFNetClientS
{
public:
/// NFNetClient 생성자
NFNetClientS();
/// NFNetClient 소멸자
virtual ~NFNetClientS();
public:
/// 로컬 IP를 얻어옵니다.
void GetLocalIP(CHAR* LocalIP);
/// Connect상태를 얻어옵니다.
BOOL IsConnect() { return m_bConnect; }
/// 패킷을 Send 합니다.
BOOL SendPost(NFPacket& Packet);
/**
* @brief 클래스 초기화.
* @param szIP 접속할 아이피
* @param nPort 접속할 포트
* @return 성공여부
*/
BOOL Init(LPCSTR szIP, int nPort);
/// Disconnect 시킵니다.
virtual void Disconnect();
/// Network를 업데이트 합니다.
virtual void Update();
/// 클라이언트 정지
void Stop();
/// 모든 객체를 Close 합니다.
void CloseAll();
private:
/// 소켓 이벤트
virtual void OnSocketEvent(DWORD dID, DWORD dEvent) {};
/// 패킷 프로세싱
virtual void ProcessPacket(NFPacket* Packet, int PacketLen) { };
/// 소켓 이벤트 핸들러
BOOL NetworkEventHanlder(LONG lEvent);
private:
/// Event Thread
static DWORD WINAPI EventThreadProc(LPVOID lParam);
/// Send 이벤트 처리
VOID OnSendPacketData();
/// Recv 이벤트 처리
VOID OnReadPacketData();
/// RecvQue의 개수
int GetQueCnt();
/// 첫 패킷 얻어오기
int GetPacket(NFPacket** Packet);
/// 큐에서 패킷을 꺼낸다.
void PopPacket();
/// 큐를 업데이트 한다.
void UpdateQue();
/// Connect 소켓이벤트
BOOL OnConnect();
/// Close 소켓이벤트
BOOL OnClose();
/// 서버와 Connect를 합니다.
BOOL Connect();
/// 윈속 초기화
BOOL WinSockInit();
private:
/// 클라이언트 소켓
SOCKET m_hSocket;
/// 포트
UINT m_nPort;
/// Server IP저장
CHAR m_strIPAddr[32];
/// Recv Queue
NFPacketQueue m_RecvQueue;
/// Send Queue
NFPacketQueue m_SendQueue;
/// 네트워크 이벤트 핸들러
WSAEVENT m_hEvent;
/// Close 된상태인지
BOOL m_bClose;
/// 접속 상태 플래그
BOOL m_bConnect;
/// RecvIO Buffer (완성된 패킷이 저장됨)
NFPacketIOBuffer m_RecvIO;
/// RecvPacket 변수 (완성된 한개의 패킷)
NFPacket m_RecvPacket;
/// Recv Buffer (스레드에서 패킷을 받을때 사용)
CHAR m_RecvBuffer[DEF_MAXPACKETSIZE];
/// Recv 스레드 핸들
HANDLE m_hEventThread;
};
}

View File

@@ -0,0 +1,82 @@
#include "NFNet.h"
#include "NFPacket.h"
#include "GZip/zlib.h"
#pragma comment(lib,"zlib.lib")
namespace NaveNet {
NFPacket::NFPacket()
{
Init();
}
NFPacket::~NFPacket()
{
}
VOID NFPacket::Init()
{
ZeroMemory(&m_Header, sizeof(PACKETHEADER));
ZeroMemory(m_Packet, sizeof(m_Packet));
}
int NFPacket::EncryptPacket()
{
// 체크섬 생성순서.
// 1. 헤더 생성 (사이즈및 커맨드 설정.)
// 2. 암호화 및 압축
// 3. 체크섬 생성.
m_Header.CheckSum = ((m_Header.Command+m_Header.Size+m_Packet[0]+m_Packet[1])^0xA6F69E23)^0x62F2EA02;
// 사이즈가 100바이트 이상이면 압축하고 체크섬 설정
if(m_Header.Size >= 100)
{
m_Header.CheckSum = m_Header.CheckSum|0xF0000000;
// 압축하기
// m_Header.Size 사이즈 재조정
uLongf destLen;
int srcLen = GetSize();
char srcBuff[DEF_PACKETSIZE];
memcpy(srcBuff, m_Packet, srcLen);
compress2((Bytef*)m_Packet, &destLen, (Bytef*)srcBuff, srcLen, 5);
m_Packet[destLen]=0;
SetSize((USHORT)destLen);
}
else
m_Header.CheckSum = m_Header.CheckSum&0x0FFFFFFF;
return m_Header.Size;
}
VOID NFPacket::DecryptPacket()
{
if(m_Header.CheckSum&0xF0000000)
{
// 압축풀기
// m_Header.Size 사이즈 재조정
uLongf destLen;
int srcLen = GetSize();
char srcBuff[DEF_PACKETSIZE];
memcpy(srcBuff, m_Packet, srcLen);
uncompress((Bytef*)m_Packet, &destLen, (Bytef*)srcBuff, srcLen);
m_Packet[destLen]=0;
SetSize((USHORT)destLen);
}
// 체크섬 조정
m_Header.CheckSum = m_Header.CheckSum&0x0FFFFFFF;
}
BOOL NFPacket::IsAliveChecksum()
{
DWORD CheckSum = ((m_Header.Command+m_Header.Size+m_Packet[0]+m_Packet[1])^0xA6F69E23)^0x62F2EA02;
CheckSum = CheckSum&0x0FFFFFFF;
if(m_Header.CheckSum == CheckSum)
return TRUE;
return FALSE;
}
}

View File

@@ -0,0 +1,136 @@
/**
* @file NFPacket.h
* @brief 패킷 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#ifdef _WIN32
#pragma pack( push ,1 )
#else
#pragma pack(1)
#endif
namespace NaveNet {
#define DEF_BUFSIZE 1024 /// Mem Pool and Socket Buffer size
#define DEF_PACKETSIZE 1016 /// Packet Size
#define DEF_MAXPACKETSIZE 1024 /// Max Packet Size ( Header + Packet )
#define CONNECT_CHECK_DATA "NAV" /// CheckSum 패킷 (처음으로 Server에 Connect 한후 전달된다)
#define CONNECT_CHECK_SIZE 4 /// 초기 접속 오는 패킷 사이즈 ** WARINING **
/// 패킷 헤더 구조체
typedef struct PACKETHEADER
{
USHORT Size; /// 실제 패킷 크기
USHORT Command; /// 패킷의 종류
DWORD CheckSum; /// 체크섬
}*LPPACKETHEADER;
#define HEADERSIZE 8 /// 패킷 헤더의 사이즈
/**
* @class NFPacket
* @brief 한개의 패킷을 관리 하기 위한 클래스 객체
* @remarks 패킷의 구조 \r\n
\r\n
Header( Size, Command) + CheckSum + Data \r\n
------------------------------------------------------------0-------------------\r\n
| 2byte | 2byte | CheckSum(4Byte) | Header.Size-Header 만큼의 실제 Packet 용량 |\r\n
--------------------------------------------------------------00----------------\r\n
\r\n
예) \r\n
#define USER_LOGIN 1 \r\n
\r\n
typedef struct stLogin \r\n
{ \r\n
CHAR UserID[16]; \r\n
CHAR UserPass[12]; \r\n
}LOGIN, *LPLOGIN; \r\n
\r\n
// Header 정보 \r\n
Packet.m_Header.Size = sizeof(LOGIN); \r\n
Packet.m_Header.Command = USER_LOGIN; \r\n
\r\n
// 사용법 \r\n
static LPLOGIN login = (LPLOGIN)Packet.m_Packet; \r\n
login->UserID; \r\n
login->UserPass; \r\n
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFPacket
{
public:
/// NFPacket 생성자
NFPacket();
/// NFPacket 소멸자
~NFPacket();
/// 패킷 초기화
VOID Init();
/**
* @brief 헤더의 Command 얻기
* @return Command 정보
*/
inline USHORT GetCommand() const
{
return m_Header.Command;
}
/**
* @brief 헤더에 Command를 지정한다.
* @param shCommand Command 값
*/
inline VOID SetCommand(USHORT shCommand)
{
m_Header.Command = shCommand;
}
/**
* @brief 패킷 사이즈 구하기
* @return 패킷 사이즈
*/
inline int GetSize()
{
return m_Header.Size-HEADERSIZE;
}
/**
* @brief 패킷의 사이즈를 지정한다.
* @param shDataSize
*/
inline VOID SetSize(USHORT shDataSize)
{
// Size = Header + DataSize;
m_Header.Size = HEADERSIZE + shDataSize;
}
/// 패킷을 암호화한다.
int EncryptPacket();
/// 패킷을 디코딩한다.
VOID DecryptPacket();
/// CheckSum 변수와 새로 생성한 체크섬이 동일한지 검사한다.
BOOL IsAliveChecksum();
public:
/// 패킷의 헤더 정보
PACKETHEADER m_Header;
/// 실제 패킷의 정보
CHAR m_Packet[DEF_PACKETSIZE];
};
}
#pragma pack()

View File

@@ -0,0 +1,80 @@
/**
* @file NFSync.h
* @brief Sync 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
namespace NaveNet {
/**
* @class NFSync
* @brief Sync 클래스
* @remarks
* NFSync Sync; \r\n
* NFSyncLock CL(&Sync);
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFSync
{
public:
NFSync(VOID)
{
InitializeCriticalSection(&m_Sync);
}
~NFSync(VOID)
{
DeleteCriticalSection(&m_Sync);
}
inline VOID Enter(VOID)
{
EnterCriticalSection(&m_Sync);
}
inline VOID Leave(VOID)
{
LeaveCriticalSection(&m_Sync);
}
private:
CRITICAL_SECTION m_Sync;
};
/**
* @class NFSyncLock
* @brief 싱글스레드용 싱크
* @remarks
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFSyncLock
{
public:
NFSyncLock(LPVOID lpVoid)
{
m_pThis = (NFSync*)lpVoid;
m_pThis->Enter();
}
~NFSyncLock(VOID)
{
if(m_pThis)
m_pThis->Leave();
}
private:
NFSync *m_pThis;
};
}

View File

@@ -0,0 +1,22 @@
========================================================================
정적 라이브러리 : NaveNet 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 NaveNet 라이브러리를 만들었습니다.
프로젝트에 대해 소스 파일은 만들어지지 않았습니다.
NaveNet.vcproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
파일을 생성한 Visual C++ 버전에 대한 정보와
응용 프로그램 마법사를 사용하여 선택한 플랫폼, 구성 및 프로젝트 기능에 대한
정보가 들어 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,132 @@
#include "NetAuth.h"
using namespace NaveNet;
CNetAuth::CNetAuth(void) : m_event(0)
{
// 함수를 Map으로 선언한다.
OnMsgMap[CMD] = &CNetAuth::Parsed_CMD;
OnMsgMap[AUTH] = &CNetAuth::Parsed_Dummy;
OnMsgMap[IPLIST] = &CNetAuth::Parsed_IPLIST;
OnMsgMap[IRC] = &CNetAuth::Parsed_IRC;
}
CNetAuth::~CNetAuth(void)
{
m_event = NULL;
Disconnect();
}
void CNetAuth::Disconnect()
{
NFNetClientS::Disconnect();
m_SendPacket.Init();
}
void CNetAuth::OnSocketEvent(DWORD dID, DWORD dEvent)
{
// 소켓에서 일어난 이벤트를 처리하기 위한것.
if(dID == WM_CONNECT) // 접속 이벤트
{
if(m_event)
m_event->EventConnect(dEvent);
}
else if(dID == WM_SOCK_CLOSE) // 소켓 종료 이벤트
{
if(m_event)
m_event->EventSocketClose();
}
else if(dID == WM_RECV_MSG) // 패킷 한개 받은 이벤트
{
// Test할때만 사용된다 나중에 정식으로 들어가면 빠진다.
// ::PostMessage(m_hWnd, dID, dEvent, NULL); // 완전한 Packet Data return
}
}
void CNetAuth::Update()
{
// Socket Update;
NFNetClientS::Update();
// 기타처리
}
void CNetAuth::ProcessPacket(NFPacket* pPacket, int PacketLen)
{
// 함수 호출
(this->*OnMsgMap[pPacket->GetCommand()])(pPacket->m_Packet, pPacket->GetSize());
}
void CNetAuth::Parsed_IRC(CHAR* Packet, int Len)
{
LPPKIRC pkIRC = (LPPKIRC)Packet;
if(m_event)
m_event->EventIRC(pkIRC->Key, pkIRC->Message);
}
void CNetAuth::Parsed_Dummy(CHAR* Packet, int Len)
{
}
void CNetAuth::Parsed_CMD(CHAR* Packet, int Len)
{
LPPKCMD pkPar = (LPPKCMD)Packet;
if(m_event)
m_event->EventCMD(pkPar->dwCmd, pkPar->dwValue);
}
void CNetAuth::Parsed_IPLIST(CHAR* Packet, int Len)
{
LPPKIPLIST lpPk = (LPPKIPLIST)Packet;
char* Buffer_Out = (char*)Packet+sizeof(PKIPLIST);
if(m_event)
m_event->EventIPLIST(lpPk->Type, lpPk->Page, lpPk->Count, Buffer_Out);
}
void CNetAuth::Send_IRC(const char* strCommand, const char* strMsg)
{
// Sync::CLive CL(&m_Cs);
m_SendPacket.SetCommand(IRC);
m_SendPacket.SetSize(sizeof(PKIRC));
LPPKIRC lpIRC = (LPPKIRC)m_SendPacket.m_Packet;
strcpy(lpIRC->Key, strCommand);
strcpy(lpIRC->Message, strMsg);
SendPost(m_SendPacket);
}
void CNetAuth::Send_AUTH(DWORD dwType, const char* strKey)
{
m_SendPacket.SetCommand(AUTH);
m_SendPacket.SetSize(sizeof(PKAUTH));
LPPKAUTH lpPk = (LPPKAUTH)m_SendPacket.m_Packet;
lpPk->Type = dwType;
memcpy(lpPk->Key, strKey, sizeof(lpPk->Key));
SendPost(m_SendPacket);
}
void CNetAuth::Send_CMD(DWORD dwCmd, DWORD dwValue)
{
m_SendPacket.SetCommand(CMD);
m_SendPacket.SetSize(sizeof(PKCMD));
LPPKCMD lpPk = (LPPKCMD)m_SendPacket.m_Packet;
lpPk->dwCmd = dwCmd;
lpPk->dwValue = dwValue;
SendPost(m_SendPacket);
}

View File

@@ -0,0 +1,79 @@
#pragma once
#include "NaveNet/NFNet.h"
#include "NaveNet/NFNetClientS.h"
#include "Packet.h"
class CNetAuth : public NaveNet::NFNetClientS
{
public:
CNetAuth(void);
~CNetAuth(void);
public:
//////////////////////////////////////////////////////////////////////
// Socket -> Client로 패킷을 전달하기 위해 존재하는 Listener이다.
//////////////////////////////////////////////////////////////////////
class IEventListener
{
public:
virtual ~IEventListener() {}
virtual void EventIRC(CHAR* strCmd, CHAR* strMsg)=0;
virtual void EventCMD(DWORD dwCmd, DWORD dwValue)=0;
virtual void EventIPLIST(CHAR Type, CHAR Page, SHORT Count, char* lpIPList_Out)=0;
virtual void EventConnect(BOOL bConnect)=0;
virtual void EventSocketClose()=0;
};
void SetEventListener(IEventListener* event)
{
m_event = event;
}
public:
virtual void Update();
//////////////////////////////////////////////////////////////////////
// ToServer에 정의된 패킷사용
// 전달받은 패킷이 처리될 패킷함수 형식은 Recv_패킷이름(CHAR* Packet, int Len) 이된다.
//////////////////////////////////////////////////////////////////////
void Send_IRC(const char* strCommand, const char* strMsg);
void Send_AUTH(DWORD dwType, const char* strKey);
void Send_CMD(DWORD dwCmd, DWORD dwValue);
void Disconnect();
private:
//////////////////////////////////////////////////////////////////////
// CNetAuth에서 사용되는 변수모음
//////////////////////////////////////////////////////////////////////
// Nave::Sync::CSync m_Cs;
// Send를 하기위해 패킷을 만들때 사용된다.
NaveNet::NFPacket m_SendPacket;
IEventListener* m_event;
private:
void (CNetAuth::*OnMsgMap[MaxPacket])(CHAR* Packet, int Len);
// 소켓 부분에서 떨어지는 이벤트를 처리할때
void OnSocketEvent(DWORD dID, DWORD dEvent);
//////////////////////////////////////////////////////////////////////
// FromServer에 정의된 패킷사용 (클라이언트는 상관없다.)
// 전달받은 패킷이 처리될 패킷함수 형식은 Recv_패킷이름(CHAR* Packet, int Len) 이된다.
//////////////////////////////////////////////////////////////////////
// IRC Packet 처리함수
void Parsed_CMD(CHAR* Packet, int Len);
void Parsed_IPLIST(CHAR* Packet, int Len);
void Parsed_Dummy(CHAR* Packet, int Len);
void Parsed_IRC(CHAR* Packet, int Len);
void ProcessPacket(NaveNet::NFPacket* pPacket, int PacketLen);
};

View File

@@ -0,0 +1,76 @@
#pragma once
#include <windows.h>
enum PACKETLIST
{
NONE = 0,
CMD,
AUTH, // 각 어플리케이션의 인증을 시도한다.
IPLIST, // 접속가능한 IP리스트를 전달한다.
IRC,
MaxPacket,
};
enum Result
{
R_ERROR = 0,
R_OK,
};
enum AUTHTYPE
{
AT_NONE = 0,
AT_LOGIN = 1,
AT_UID,
AT_DBAGENT,
AT_AUTH,
AT_CHAT,
AT_ZONE,
};
enum CMDTYPE
{
CMD_NONE = 0,
CS_IPLIST = 1,
SC_SHUTDOWN = 101, // 종료시켜라 ( S->C ) NFNetClient가 포함된 어플리케이션을 종료한다.
SC_CRASH = 201,
};
typedef struct PKIRC
{
CHAR Key[64];
CHAR Message[512];
}*LPPKIRC;
typedef struct PKAUTH
{
DWORD Type; // 타입 타입은 상위, 하위 워드로 이루어지며 하위는 타입, 상위는 존번호등이다.
CHAR Key[40]; // 인증코드
}*LPPKAUTH;
typedef struct IPINFO
{
DWORD start;
DWORD end;
}*LPIPINFO;
typedef struct PKIPLIST
{
enum { ALLOWIP, BLOCKIP };
CHAR Type;
CHAR Page;
SHORT Count;
}*LPPKIPLIST;
// AUTHServer에서 AuthClient로 결과를 전달한다.
// 이결과에 따라 AuthClient는 행동한다 (셧다운등등)
typedef struct PKCMD
{
DWORD dwCmd;
DWORD dwValue;
}*LPPKCMD;

View File

@@ -0,0 +1,21 @@
========================================================================
정적 라이브러리 : NFAuthClient 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 NFAuthClient 라이브러리 프로젝트를 만들었습니다.
프로젝트에 대해 소스 파일은 만들어지지 않았습니다.
NFAuthClient.vcproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
프로젝트 기능에 대한 정보가 들어 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,368 @@
192.168.0.0 192.168.0.255 LO
58.26.0.0 58.27.127.255 MY
58.71.128.0 58.71.255.255 MY
58.139.0.0 58.139.255.255 MY
60.48.0.0 60.54.255.255 MY
61.4.96.0 61.4.127.255 MY
61.6.0.0 61.6.191.255 MY
61.11.208.0 61.11.223.255 MY
61.14.42.200 61.14.42.207 MY
61.14.135.0 61.14.135.47 MY
61.14.135.64 61.14.135.95 MY
61.14.136.0 61.14.136.103 MY
61.14.136.176 61.14.136.191 MY
61.14.136.208 61.14.136.223 MY
61.14.137.8 61.14.137.31 MY
61.14.138.96 61.14.138.103 MY
61.14.138.192 61.14.138.207 MY
61.14.139.32 61.14.139.55 MY
61.14.139.128 61.14.139.159 MY
61.14.139.176 61.14.139.183 MY
61.14.145.0 61.14.145.127 MY
61.14.160.0 61.14.162.255 MY
61.28.201.0 61.28.201.255 MY
64.37.74.0 64.37.74.255 MY
64.37.85.0 64.37.85.255 MY
64.119.163.0 64.119.163.7 MY
64.119.163.232 64.119.163.255 MY
64.119.164.104 64.119.164.111 MY
64.119.165.224 64.119.165.255 MY
64.119.167.192 64.119.167.207 MY
64.119.169.16 64.119.169.39 MY
64.119.169.128 64.119.169.135 MY
64.119.169.208 64.119.169.215 MY
64.119.170.72 64.119.170.95 MY
64.119.171.80 64.119.171.103 MY
64.119.171.160 64.119.171.191 MY
65.19.167.112 65.19.167.119 MY
66.201.112.0 66.201.112.127 MY
67.222.149.171 67.222.149.178 MY
69.13.184.12 69.13.184.20 MY
72.249.0.96 72.249.0.127 MY
89.248.174.192 89.248.174.223 MY
110.4.40.0 110.4.47.255 MY
110.74.128.0 110.74.191.255 MY
110.159.0.0 110.159.255.255 MY
111.67.32.0 111.67.47.255 MY
111.90.128.0 111.90.159.255 MY
111.221.48.0 111.221.55.255 MY
112.137.160.0 112.137.175.255 MY
113.21.128.0 113.21.159.255 MY
113.23.128.0 113.23.255.255 MY
113.210.0.0 113.211.255.255 MY
113.212.108.0 113.212.111.255 MY
114.133.0.0 114.133.255.255 MY
115.85.128.0 115.85.128.255 MY
115.132.0.0 115.135.255.255 MY
115.146.96.0 115.146.111.255 MY
115.164.0.0 115.164.255.255 MY
116.0.8.0 116.0.15.255 MY
116.0.64.0 116.0.64.63 MY
116.0.96.0 116.0.127.255 MY
116.197.0.0 116.197.127.255 MY
116.206.0.0 116.206.255.255 MY
118.100.0.0 118.101.255.255 MY
118.107.192.0 118.107.255.255 MY
119.40.112.0 119.40.127.255 MY
119.110.0.0 119.110.63.255 MY
119.110.96.0 119.110.111.255 MY
119.110.128.0 119.110.255.255 MY
119.161.96.0 119.161.103.255 MY
120.50.48.0 120.50.63.255 MY
120.138.80.0 120.138.95.255 MY
120.139.0.0 120.141.255.255 MY
121.120.0.0 121.123.255.255 MY
122.0.16.0 122.0.31.255 MY
122.255.96.0 122.255.127.255 MY
123.100.224.0 123.100.225.255 MY
123.136.96.0 123.136.127.255 MY
124.13.0.0 124.13.255.255 MY
124.82.0.0 124.82.255.255 MY
124.150.140.0 124.150.143.255 MY
124.195.128.0 124.195.143.255 MY
124.197.224.0 124.197.255.255 MY
124.217.224.0 124.217.255.255 MY
144.199.0.0 144.199.255.255 MY
161.139.0.0 161.139.255.255 MY
161.142.0.0 161.142.255.255 MY
170.38.0.0 170.38.255.255 MY
180.72.0.0 180.75.255.255 MY
192.228.128.0 192.228.255.255 MY
194.117.103.12 194.117.103.12 MY
194.117.103.18 194.117.103.18 MY
194.117.103.33 194.117.103.34 MY
194.117.103.48 194.117.103.48 MY
194.117.103.50 194.117.103.50 MY
194.117.103.52 194.117.103.52 MY
194.117.103.54 194.117.103.54 MY
194.117.103.56 194.117.103.57 MY
194.117.103.83 194.117.103.83 MY
194.117.103.85 194.117.103.85 MY
194.117.103.92 194.117.103.92 MY
194.117.103.95 194.117.103.95 MY
194.117.103.104 194.117.103.104 MY
194.117.103.106 194.117.103.107 MY
194.117.103.114 194.117.103.114 MY
194.117.103.119 194.117.103.119 MY
194.117.103.122 194.117.103.122 MY
194.117.103.125 194.117.103.126 MY
194.117.103.139 194.117.103.141 MY
194.117.103.145 194.117.103.146 MY
194.117.103.148 194.117.103.149 MY
194.117.103.167 194.117.103.167 MY
194.117.103.171 194.117.103.171 MY
194.117.103.174 194.117.103.175 MY
194.117.103.179 194.117.103.179 MY
194.117.103.187 194.117.103.187 MY
194.117.103.192 194.117.103.192 MY
194.117.103.196 194.117.103.196 MY
194.117.103.198 194.117.103.198 MY
194.117.103.202 194.117.103.202 MY
194.117.103.204 194.117.103.204 MY
194.117.103.211 194.117.103.211 MY
194.117.103.216 194.117.103.216 MY
194.117.103.223 194.117.103.223 MY
194.117.103.225 194.117.103.225 MY
194.117.103.228 194.117.103.228 MY
194.117.103.233 194.117.103.233 MY
194.117.103.235 194.117.103.235 MY
194.117.103.240 194.117.103.240 MY
194.117.103.242 194.117.103.242 MY
194.117.103.251 194.117.103.252 MY
195.112.167.4 195.112.167.7 MY
195.112.167.32 195.112.167.35 MY
195.112.167.48 195.112.167.51 MY
195.112.167.60 195.112.167.63 MY
195.112.167.68 195.112.167.75 MY
195.112.167.92 195.112.167.95 MY
195.112.167.180 195.112.167.187 MY
195.112.167.200 195.112.167.203 MY
195.112.167.240 195.112.167.247 MY
195.112.177.4 195.112.177.7 MY
195.112.177.28 195.112.177.31 MY
195.112.177.36 195.112.177.43 MY
195.112.177.84 195.112.177.87 MY
195.112.177.96 195.112.177.107 MY
195.112.177.112 195.112.177.115 MY
195.112.177.164 195.112.177.171 MY
195.112.177.180 195.112.177.183 MY
195.112.177.188 195.112.177.191 MY
195.112.177.204 195.112.177.207 MY
195.112.177.240 195.112.177.243 MY
202.0.94.0 202.0.94.255 MY
202.9.96.0 202.9.111.255 MY
202.21.148.0 202.21.148.255 MY
202.43.100.0 202.43.103.255 MY
202.45.132.0 202.45.143.255 MY
202.46.112.0 202.46.127.255 MY
202.47.160.0 202.47.191.255 MY
202.56.80.0 202.56.95.255 MY
202.58.80.0 202.58.95.255 MY
202.60.56.0 202.60.59.255 MY
202.71.96.0 202.71.111.255 MY
202.73.8.0 202.73.15.255 MY
202.75.4.0 202.75.7.255 MY
202.75.32.0 202.75.63.255 MY
202.75.128.0 202.75.191.255 MY
202.75.240.0 202.75.247.255 MY
202.76.224.0 202.76.239.255 MY
202.83.120.0 202.83.127.255 MY
202.87.216.0 202.87.223.255 MY
202.94.160.0 202.94.175.255 MY
202.122.144.0 202.122.159.255 MY
202.129.160.0 202.129.175.255 MY
202.133.96.0 202.133.111.255 MY
202.137.252.0 202.137.255.255 MY
202.144.192.0 202.144.207.255 MY
202.146.64.0 202.146.95.255 MY
202.147.34.64 202.147.34.79 MY
202.147.37.0 202.147.37.15 MY
202.147.39.24 202.147.39.39 MY
202.147.39.160 202.147.39.223 MY
202.151.192.0 202.151.255.255 MY
202.157.176.0 202.157.177.255 MY
202.157.182.0 202.157.189.255 MY
202.162.0.0 202.162.31.255 MY
202.165.0.0 202.165.31.255 MY
202.168.64.0 202.168.79.255 MY
202.170.48.0 202.170.63.255 MY
202.171.32.0 202.171.63.255 MY
202.171.192.0 202.171.207.255 MY
202.174.130.0 202.174.131.31 MY
202.174.131.40 202.174.131.47 MY
202.174.131.56 202.174.131.87 MY
202.174.131.112 202.174.131.119 MY
202.174.131.136 202.174.131.143 MY
202.174.131.152 202.174.131.167 MY
202.174.131.232 202.174.131.247 MY
202.174.132.0 202.174.132.207 MY
202.174.133.64 202.174.133.127 MY
202.174.133.232 202.174.133.239 MY
202.174.134.64 202.174.134.191 MY
202.174.135.0 202.174.135.119 MY
202.174.135.184 202.174.135.191 MY
202.174.135.208 202.174.135.255 MY
202.174.143.24 202.174.143.39 MY
202.174.143.48 202.174.143.87 MY
202.174.143.104 202.174.143.111 MY
202.174.143.128 202.174.143.143 MY
202.174.143.152 202.174.143.159 MY
202.174.143.208 202.174.143.215 MY
202.174.144.8 202.174.144.15 MY
202.174.144.64 202.174.144.71 MY
202.174.144.88 202.174.144.127 MY
202.174.144.136 202.174.144.143 MY
202.174.144.152 202.174.144.167 MY
202.174.144.208 202.174.144.215 MY
202.174.153.24 202.174.153.31 MY
202.174.153.48 202.174.153.63 MY
202.174.153.80 202.174.153.95 MY
202.174.153.104 202.174.153.111 MY
202.174.153.144 202.174.153.159 MY
202.174.153.240 202.174.153.255 MY
202.174.154.112 202.174.154.119 MY
202.174.154.168 202.174.154.175 MY
202.174.155.184 202.174.155.191 MY
202.174.155.233 202.174.155.239 MY
202.174.155.248 202.174.155.255 MY
202.176.12.0 202.176.13.255 MY
202.178.0.0 202.178.79.255 MY
202.179.96.0 202.179.127.255 MY
202.184.0.0 202.188.255.255 MY
202.190.0.0 202.190.255.255 MY
202.191.128.0 202.191.255.255 MY
203.10.16.0 203.10.23.255 MY
203.12.220.0 203.12.220.255 MY
203.62.1.0 203.62.1.255 MY
203.78.192.0 203.78.207.255 MY
203.80.16.0 203.80.23.255 MY
203.82.64.0 203.82.95.255 MY
203.88.66.96 203.88.66.103 MY
203.88.66.152 203.88.66.159 MY
203.88.66.168 203.88.66.175 MY
203.88.66.192 203.88.66.199 MY
203.88.66.232 203.88.66.255 MY
203.88.81.0 203.88.82.7 MY
203.88.88.80 203.88.88.95 MY
203.88.88.104 203.88.88.119 MY
203.88.88.200 203.88.88.207 MY
203.92.128.0 203.92.159.255 MY
203.98.195.80 203.98.195.95 MY
203.99.136.0 203.99.139.255 MY
203.106.0.0 203.106.255.255 MY
203.109.32.0 203.109.63.255 MY
203.112.224.0 203.112.255.255 MY
203.114.0.0 203.114.63.255 MY
203.115.192.0 203.115.255.255 MY
203.119.57.0 203.119.57.255 MY
203.121.0.0 203.121.127.255 MY
203.135.190.0 203.135.191.255 MY
203.142.0.0 203.142.7.255 MY
203.142.32.0 203.142.63.255 MY
203.148.88.0 203.148.91.255 MY
203.153.16.0 203.153.23.255 MY
203.153.80.0 203.153.95.255 MY
203.158.24.0 203.158.31.255 MY
203.161.48.0 203.161.48.255 MY
203.163.78.16 203.163.78.23 MY
203.163.78.32 203.163.78.55 MY
203.163.78.64 203.163.78.79 MY
203.163.105.48 203.163.105.63 MY
203.163.105.80 203.163.105.87 MY
203.163.105.96 203.163.105.127 MY
203.176.144.0 203.176.151.255 MY
203.188.232.0 203.188.239.255 MY
203.189.16.0 203.189.23.255 MY
203.192.141.192 203.192.141.207 MY
203.192.177.0 203.192.177.31 MY
203.194.74.128 203.194.74.143 MY
203.194.74.152 203.194.74.195 MY
203.201.182.0 203.201.182.255 MY
203.201.184.0 203.201.187.255 MY
203.215.60.0 203.215.63.255 MY
203.217.128.0 203.217.131.255 MY
203.217.176.0 203.217.179.255 MY
203.223.128.0 203.223.159.255 MY
204.244.106.48 204.244.106.55 MY
205.214.67.80 205.214.67.87 MY
206.41.117.160 206.41.117.167 MY
206.73.198.0 206.73.198.63 MY
206.73.249.96 206.73.249.111 MY
206.182.221.64 206.182.221.95 MY
206.182.243.224 206.182.243.255 MY
207.209.93.64 207.209.93.71 MY
207.209.99.0 207.209.99.255 MY
209.28.42.0 209.28.42.255 MY
209.28.58.0 209.28.58.127 MY
209.28.242.0 209.28.242.255 MY
209.51.201.224 209.51.201.231 MY
209.93.43.80 209.93.43.87 MY
209.93.100.128 209.93.100.191 MY
209.93.120.0 209.93.120.15 MY
209.93.166.64 209.93.166.127 MY
209.93.239.0 209.93.239.255 MY
209.151.66.120 209.151.66.127 MY
209.151.92.0 209.151.92.255 MY
209.190.17.8 209.190.17.15 MY
209.197.228.48 209.197.228.95 MY
209.197.235.216 209.197.235.223 MY
209.197.237.48 209.197.237.191 MY
209.197.239.8 209.197.239.23 MY
209.197.239.32 209.197.239.255 MY
210.5.40.0 210.5.47.255 MY
210.19.0.0 210.19.255.255 MY
210.48.144.0 210.48.159.255 MY
210.48.192.0 210.48.207.255 MY
210.48.216.0 210.48.223.255 MY
210.186.0.0 210.187.39.127 MY
210.187.40.0 210.187.255.255 MY
210.195.0.0 210.195.255.255 MY
211.24.0.0 211.25.255.255 MY
212.63.181.8 212.63.181.11 MY
212.63.181.24 212.63.181.27 MY
212.63.181.32 212.63.181.35 MY
212.63.181.48 212.63.181.51 MY
212.63.181.68 212.63.181.71 MY
212.63.181.96 212.63.181.99 MY
212.63.181.104 212.63.181.107 MY
212.63.181.132 212.63.181.135 MY
212.63.181.168 212.63.181.171 MY
212.63.181.208 212.63.181.211 MY
212.63.181.240 212.63.181.243 MY
212.63.183.2 212.63.183.2 MY
212.63.183.11 212.63.183.11 MY
212.63.183.16 212.63.183.16 MY
212.63.183.18 212.63.183.18 MY
212.63.183.22 212.63.183.22 MY
212.63.183.27 212.63.183.27 MY
212.63.183.59 212.63.183.59 MY
212.63.183.75 212.63.183.77 MY
212.63.183.81 212.63.183.81 MY
212.63.183.172 212.63.183.175 MY
212.63.183.236 212.63.183.239 MY
216.7.172.128 216.7.172.143 MY
216.15.133.32 216.15.133.63 MY
216.15.157.32 216.15.157.63 MY
216.15.158.128 216.15.158.255 MY
216.15.178.192 216.15.178.254 MY
216.15.180.0 216.15.180.127 MY
216.15.187.0 216.15.187.254 MY
216.15.199.0 216.15.199.255 MY
216.15.212.192 216.15.212.255 MY
216.15.223.224 216.15.223.255 MY
216.15.236.32 216.15.236.95 MY
216.38.52.26 216.38.52.29 MY
216.38.52.155 216.38.52.158 MY
216.198.193.160 216.198.193.191 MY
216.198.195.0 216.198.195.255 MY
216.198.196.128 216.198.196.255 MY
217.77.242.240 217.77.242.240 MY
218.100.18.0 218.100.18.255 MY
218.100.22.0 218.100.22.255 MY
218.100.44.0 218.100.44.255 MY
218.100.58.0 218.100.58.255 MY
218.111.0.0 218.111.255.255 MY
218.208.0.0 218.208.255.255 MY
219.92.0.0 219.94.127.255 MY
219.95.0.0 219.95.255.255 MY
221.133.32.0 221.133.47.255 MY

View File

@@ -0,0 +1,20 @@
[WINDOWS]
TITLE=NFAuthServer
WIDTH=320
HEIGHT=400
[SERVER]
PORT=14050
MAXCONN=200
[DB]
IP=192.168.0.7
NAME=ROW_Auth
USER=nave
PASSWORD=nave0508
TABLE=ItemLog
[IPSEC]
ENABLE=TRUE
ALLOWIP=./AllowIPList.txt
BLOCKIP=./BlockIPList.txt

View File

@@ -0,0 +1,57 @@
#include "Global.h"
#include "DBcomponent.h"
#include "Nave/NFStringUtil.h"
namespace DBComponent
{
bool Test(NaveServer::NFDBComponent& DBComponent)
{
/*
char szQuery[NaveServer::NFDBComponent::QUERY_BUFFER_LEN];
if (_snprintf(szQuery, NaveServer::NFDBComponentQUERY_BUFFER_LEN - 1, "InsertUser %d, %d",
UserID_In, cOldServerGroupID))
{
if (DBComponent.ExecuteQuery(szQuery))
{
return true;
}
}
*/
return false;
}
bool CheckAuthCode(NaveServer::NFDBComponent& DBComponent, const char* pCode, const char* pIP)
{
WCHAR szQuery[NaveServer::NFDBComponent::QUERY_BUFFER_LEN];
if (_snwprintf(szQuery, NaveServer::NFDBComponent::QUERY_BUFFER_LEN - 1,
L"AuthCode '%s', '%s'", Nave::ToUnicode(pCode).c_str(), Nave::ToUnicode(pIP).c_str()))
{
if (DBComponent.ExecuteQuery(szQuery))
{
return true;
}
}
return false;
}
bool AddItemLog(NaveServer::NFDBComponent& DBComponent, unsigned long CreateID, unsigned long UID, unsigned long CID, unsigned short ItemPrototypeID, unsigned short Amount)
{
WCHAR szQuery[NaveServer::NFDBComponent::QUERY_BUFFER_LEN];
if (_snwprintf(szQuery, NaveServer::NFDBComponent::QUERY_BUFFER_LEN - 1,
L"INSERT INTO [ItemLog] (CreateID, UID, CID, ItemPrototypeID, Amount) VALUES (%d, %d, %d, %d, %d)",
CreateID, UID, CID, ItemPrototypeID, Amount))
{
if (DBComponent.ExecuteQuery(szQuery))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Global.h"
namespace DBComponent
{
bool Test(NaveServer::NFDBComponent& DBComponent);
bool CheckAuthCode(NaveServer::NFDBComponent& DBComponent, const char* pCode, const char* pIP);
bool AddItemLog(NaveServer::NFDBComponent& DBComponent, unsigned long CreateID, unsigned long UID, unsigned long CID, unsigned short ItemPrototypeID, unsigned short Amount);
}

View File

@@ -0,0 +1,234 @@
#include "Global.h"
#include <Nave/NFLog.h>
#include <Nave/NFStringUtil.h>
#include "GameConnection.h"
#include "DBComponent.h"
extern "C"
{
#include "MD5/global.h"
#include "MD5/md5.h"
}
using namespace NaveNet;
GameConnection::GameConnection(void)
{
// 함수를 Map으로 선언한다.
OnMsgMap[CMD] = &GameConnection::Parsed_CMD;
OnMsgMap[AUTHOR] = &GameConnection::Parsed_AUTHOR;
OnMsgMap[IPLIST] = &GameConnection::Parsed_Dummy;
OnMsgMap[BUYITEMINFO] = &GameConnection::Parsed_BUYITEMINFO;
OnMsgMap[IRC] = &GameConnection::Parsed_IRC;
}
GameConnection::~GameConnection(void)
{
}
//////////////////////////////////////////////////////////////////////
// 변수 초기화..
//////////////////////////////////////////////////////////////////////
void GameConnection::Clear()
{
m_SendPacket.Init();
}
void GameConnection::DispatchPacket(NFPacket& Packet)
{
// InterlockedExchange((LONG*)&g_iProcessPacket,g_iProcessPacket+1);
// 함수 호출
(this->*OnMsgMap[Packet.GetCommand()])(Packet.m_Packet, Packet.GetSize());
}
void GameConnection::OnConnect(BOOL bConnect)
{
if(bConnect)
{
LOG_IMPORTANT((L"[%04d] Connect User", GetIndex()));
g_UManager.Join(this);
}
}
void GameConnection::OnDisconnect()
{
g_UManager.Levae(GetIndex());
LOG_IMPORTANT((L"[%04d] Disconnect User", GetIndex()));
m_SendPacket.Init();
}
void GameConnection::Parsed_IRC(CHAR* Packet, int Len)
{
LPPKIRC pkIRC = (LPPKIRC)Packet;
CHAR Buff[DEF_PACKETSIZE];
ZeroMemory(Buff, sizeof(Buff));
sprintf(Buff, "%s : %s", pkIRC->Key, pkIRC->Message);
Nave::String strCmd = Nave::ToString(Buff);
LOG_IMPORTANT((strCmd.c_str()));
}
void GameConnection::Parsed_CMD(CHAR* Packet, int Len)
{
LPPKCMD lpPK = (LPPKCMD)Packet;
if(lpPK->dwCmd == CS_IPLIST)
Send_IPList();
}
void GameConnection::Parsed_AUTHOR(CHAR* Packet, int Len)
{
LPPKAUTHOR lpPK = (LPPKAUTHOR)Packet;
// DB와 연동하여 MD5값을 비교. 결과를 리턴한다.
m_dwServerType = LOWORD(lpPK->Type);
m_dwServerCH = HIWORD(lpPK->Type);
Nave::String strKey = Nave::ToString(lpPK->Key);
LOG_IMPORTANT((L"AUTHOR : %d(%d) : %s", m_dwServerType, m_dwServerCH, strKey.c_str()));
char sIP[32];
GetClientIP(sIP);
// 클라에서 날라온 정보를 DB에 적는다.
if(!DBComponent::CheckAuthCode(g_DBComp, lpPK->Key, sIP))
{
LOG_ERROR((L"CheckAuthCode Faild : %d(%d) %s, %s", m_dwServerType, m_dwServerCH, strKey.c_str(), sIP));
}
}
void GameConnection::Parsed_BUYITEMINFO(CHAR* Packet, int Len)
{
// 클라에서 날라온 정보를 DB에 적는다.
LPPKBUYITEMINFO lpPK = (LPPKBUYITEMINFO)Packet;
char* Buffer_Out = (char*)Packet+sizeof(PKBUYITEMINFO);
LPNFITEMINFO ipInfo = (LPNFITEMINFO)Buffer_Out;
for(int i = 0; i < lpPK->Count; ++i, ++ipInfo)
{
if(DBComponent::AddItemLog(g_DBComp, ipInfo->CreateID, ipInfo->UID, ipInfo->CID, ipInfo->ItemPrototypeID, ipInfo->Amount) )
{
// 이정보를 DB에 쓰면 된다.
LOG_IMPORTANT((L"[Item] ID:%d UID:%d CID:%d = %d", ipInfo->CreateID, ipInfo->UID, ipInfo->CID, ipInfo->ItemPrototypeID));
}
else
{
// 이정보를 DB에 쓰면 된다.
LOG_ERROR((L"[Item] FAILD ID:%d UID:%d CID:%d = %d", ipInfo->CreateID, ipInfo->UID, ipInfo->CID, ipInfo->ItemPrototypeID));
}
}
}
void GameConnection::Parsed_Dummy(CHAR* Packet, int Len)
{
}
void GameConnection::Send_IRC(const char* strCommand, const char* strMsg)
{
m_SendPacket.SetCommand(IRC);
m_SendPacket.SetSize(sizeof(PKIRC));
LPPKIRC lpIRC = (LPPKIRC)m_SendPacket.m_Packet;
MD5_CTX context;
unsigned char digest[16] ;
memset( digest, 0, sizeof( char ) * 16 ) ;
int len = strlen(strCommand);
char strMD5[64];
strcpy(strMD5, strCommand);
MD5Init(&context);
MD5Update(&context, reinterpret_cast<unsigned char *>(strMD5), len );
MD5Final(digest, &context);
for (int i = 0; i < 16; ++i)
{
sprintf(lpIRC->Key + i * 2, "%02x", digest[i]);
}
strcpy(lpIRC->Message, strMsg);
SendPost(m_SendPacket);
}
void GameConnection::Send_CMD(DWORD dwCmd, DWORD dwValue)
{
m_SendPacket.SetCommand(CMD);
m_SendPacket.SetSize(sizeof(PKCMD));
LPPKCMD lpPk = (LPPKCMD)m_SendPacket.m_Packet;
lpPk->dwCmd = dwCmd;
lpPk->dwValue = dwValue;
SendPost(m_SendPacket);
}
void GameConnection::Send_IPList()
{
m_SendPacket.SetCommand(IPLIST);
LPPKIPLIST lpPk = (LPPKIPLIST)m_SendPacket.m_Packet;
lpPk->Type = PKIPLIST::ALLOWIP;
lpPk->Page = 0;
int iCurCount = 0;
char cPage = 0;
int iCount = 0;
while(TRUE)
{
lpPk->Type = PKIPLIST::ALLOWIP;
lpPk->Page = ++cPage;
char* Buffer_Out = (char*)m_SendPacket.m_Packet+sizeof(PKIPLIST);
lpPk->Count = g_IPSec.SerializeOut(PKIPLIST::ALLOWIP, iCount, 100, Buffer_Out);
m_SendPacket.SetSize(sizeof(PKIPLIST)+(sizeof(IPINFO)*lpPk->Count));
iCurCount = lpPk->Count;
iCount += lpPk->Count;
SendPost(m_SendPacket);
if(iCurCount < 100)
break;
}
cPage = 0;
iCount = 0;
while(TRUE)
{
lpPk->Type = PKIPLIST::BLOCKIP;
lpPk->Page = ++cPage;
char* Buffer_Out = (char*)m_SendPacket.m_Packet+sizeof(PKIPLIST);
lpPk->Count = g_IPSec.SerializeOut(PKIPLIST::BLOCKIP, iCount, 100, Buffer_Out);
m_SendPacket.SetSize(sizeof(PKIPLIST)+(sizeof(IPINFO)*lpPk->Count));
iCurCount = lpPk->Count;
iCount += lpPk->Count;
SendPost(m_SendPacket);
if(iCurCount < 100)
break;
}
Send_CMD(SC_IPLISTEND, 0);
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include "Packet.h"
// LoginServer의 UserConnect가 접속속할때 사용되는 Connect..
class GameConnection : public NaveServer::NFConnection
{
NaveNet::NFPacket m_SendPacket;
DWORD m_dwServerType;
DWORD m_dwServerCH;
public:
void Clear();
void DispatchPacket( NaveNet::NFPacket& Packet );
//------------------------ 멤 버 변 수 -------------------------//
protected:
void (GameConnection::*OnMsgMap[MaxPacket])(CHAR* Packet, int Len);
void OnConnect(BOOL bConnect);
void OnDisconnect();
public:
void Parsed_CMD(CHAR* Packet, int Len);
void Parsed_AUTHOR(CHAR* Packet, int Len);
void Parsed_IRC(CHAR* Packet, int Len);
void Parsed_BUYITEMINFO(CHAR* Packet, int Len);
void Parsed_Dummy(CHAR* Packet, int Len);
void Send_IRC(const char* strCommand, const char* strMsg);
void Send_CMD(DWORD dwCmd, DWORD dwValue);
void Send_IPList();
public:
GameConnection(void);
~GameConnection(void);
};

View File

@@ -0,0 +1,14 @@
#include "Global.h"
ServerCtrl* g_Server = NULL;
NaveServer::NFConnectionManager g_UManager;
int g_iProcessPacket = 0;
NaveServer::NFDBComponent g_DBComp;
std::wstring g_DBTable = L"";
NFIPSec g_IPSec;
void UpdateInfomation()
{
if(g_Server)
g_Server->UpdateInfo();
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <NaveServer/Global.h>
#include <NaveServer/NFServerCtrl.h>
#include <NaveServer/NFConnectionManager.h>
#include <NaveServer/NFConnection.h>
#include <NaveServer/NFConnection.h>
#include <NaveNet/NFNet.h>
#include <NaveNet/NFPacket.h>
#include <Nave/NFSync.h>
#include <NaveServer/NFDBComponent.h>
#include "GameConnection.h"
#include "ServerCtrl.h"
#include "NFIPSec.h"
extern ServerCtrl* g_Server;
extern NaveServer::NFConnectionManager g_UManager;
extern int g_iProcessPacket;
extern NaveServer::NFDBComponent g_DBComp;
extern std::wstring g_DBTable;
extern NFIPSec g_IPSec;
void UpdateInfomation();

View File

@@ -0,0 +1,30 @@
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 1
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif

View File

@@ -0,0 +1,37 @@
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));

View File

@@ -0,0 +1,337 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "global.h"
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0xa2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0xa4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@@ -0,0 +1,93 @@
// AlphaServer.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "Global.h"
#include <Nave/NFLog.h>
#include <Nave/NFTokenizer.h>
#include <Nave/NFStringUtil.h>
#include "ServerCtrl.h"
#include "resource.h"
#include <Nave/NFIni.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
Nave::NFLog::SetLogLimit(Nave::NFLog::Warning);
// Nave::NFLog::SetLogDetail(true);
WCHAR strCmd[512];
_tcscpy(strCmd, Nave::ToString(lpCmdLine).c_str());
g_Server = new ServerCtrl();
if(!g_Server)
{
return 0;
}
Nave::NFIni ini;
ini.Open(L"./Config.ini");
DWORD width, height;
WCHAR szTitle[128];
DWORD len = 128;
ini.GetValue(L"WINDOWS", L"TITLE", szTitle, len);
ini.GetValue(L"WINDOWS", L"WIDTH", &width);
ini.GetValue(L"WINDOWS", L"HEIGHT", &height);
WCHAR szAllowIP[128];
WCHAR szBlockIP[128];
WCHAR szenableIPSec[128];
BOOL enableIPSec;
ini.GetValue(L"IPSEC", L"ALLOWIP", szAllowIP, len);
ini.GetValue(L"IPSEC", L"BLOCKIP", szBlockIP, len);
ini.GetValue(L"IPSEC", L"ENABLE", szenableIPSec, len);
if(wcscmp(szenableIPSec, L"TRUE") == 0)
enableIPSec = TRUE;
else
enableIPSec = FALSE;
ini.Close();
// 테스트
IPBAND ipInfo[10];
g_IPSec.LoadAllowIP(szAllowIP);
g_IPSec.LoadBlockIP(szBlockIP);
g_IPSec.SerializeOut(0, 0, 10, (char*)ipInfo);
// g_IPSec.ClearAllowIP();
// g_IPSec.SerializeIn((char*)ipInfo, 10);
if(!g_Server->Init(hInstance, nCmdShow, width, height, szTitle, MIS(IDI_ICON1)))
return 0;
// IP체크 테스트
char szIP[32];
GetLocalIP(szIP, FALSE);
if( g_IPSec.IsAliveIP(szIP) )
{
LOG_IMPORTANT((L"Alive IP : %s", Nave::ToString(szIP).c_str() ));
}
else
{
LOG_IMPORTANT((L"Non Alive IP : %s", Nave::ToString(szIP).c_str() ));
}
if( g_IPSec.CheckBlockIP(szIP) )
{
LOG_IMPORTANT((L"Block IP : %s", Nave::ToString(szIP).c_str() ));
}
g_Server->StartCommand();
_DELETE(g_Server);
// 로그파일을 종료한다.
Nave::NFLog::CloseLog();
return 0;
}

View File

@@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NFAuthServer", "NFAuthServer.vcproj", "{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}.Debug.ActiveCfg = Debug|Win32
{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}.Debug.Build.0 = Debug|Win32
{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}.Release.ActiveCfg = Release|Win32
{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

Binary file not shown.

View File

@@ -0,0 +1,459 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="NFAuthServer"
ProjectGUID="{CD3486CC-5F0F-4FE1-8F24-5E35824F30BE}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\; .\SDK; .\SDK\Include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/NFAuthServer.exe"
LinkIncremental="2"
AdditionalLibraryDirectories=".\SDK\Lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/NFAuthServer.pdb"
SubSystem="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".\; .\SDK; .\SDK\Include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/NFAuthServer.exe"
LinkIncremental="1"
AdditionalLibraryDirectories=".\SDK\Lib"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="소스 파일"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\DBComponent.cpp">
</File>
<File
RelativePath=".\GameConnection.cpp">
</File>
<File
RelativePath=".\Global.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
</File>
<File
RelativePath=".\Main.cpp">
</File>
<File
RelativePath=".\NFIPSec.cpp">
</File>
<File
RelativePath=".\ServerCtrl.cpp">
</File>
</Filter>
<Filter
Name="헤더 파일"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\DBComponent.h">
</File>
<File
RelativePath=".\GameConnection.h">
</File>
<File
RelativePath=".\Global.h">
</File>
<File
RelativePath=".\NFIPSec.h">
</File>
<File
RelativePath=".\Packet.h">
</File>
<File
RelativePath=".\resource.h">
</File>
<File
RelativePath=".\ServerCtrl.h">
</File>
</Filter>
<Filter
Name="리소스 파일"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
<File
RelativePath=".\Script1.rc">
</File>
</Filter>
<Filter
Name="Nave"
Filter="">
<File
RelativePath=".\Nave\Nave.cpp">
</File>
<File
RelativePath=".\Nave\Nave.h">
</File>
<File
RelativePath=".\Nave\NFIni.cpp">
</File>
<File
RelativePath=".\Nave\NFIni.h">
</File>
<File
RelativePath=".\Nave\NFLog.cpp">
</File>
<File
RelativePath=".\Nave\NFLog.h">
</File>
<File
RelativePath=".\Nave\NFLogManager.cpp">
</File>
<File
RelativePath=".\Nave\NFLogManager.h">
</File>
<File
RelativePath=".\Nave\NFSingleton.h">
</File>
<File
RelativePath=".\Nave\NFStringCompare.h">
</File>
<File
RelativePath=".\Nave\NFStringGeneral.cpp">
</File>
<File
RelativePath=".\Nave\NFStringGeneral.h">
</File>
<File
RelativePath=".\Nave\NFStringGenericConversion.cpp">
</File>
<File
RelativePath=".\Nave\NFStringGenericConversion.h">
</File>
<File
RelativePath=".\Nave\NFStringUtil.h">
</File>
<File
RelativePath=".\Nave\NFSync.h">
</File>
<File
RelativePath=".\Nave\NFThread.h">
</File>
<File
RelativePath=".\Nave\NFThreadManager.cpp">
</File>
<File
RelativePath=".\Nave\NFThreadManager.h">
</File>
<File
RelativePath=".\Nave\NFTokenizer.cpp">
</File>
<File
RelativePath=".\Nave\NFTokenizer.h">
</File>
<File
RelativePath=".\Nave\NFTypes.h">
</File>
</Filter>
<Filter
Name="NaveNet"
Filter="">
<File
RelativePath=".\NaveNet\NFIOBuffer.cpp">
</File>
<File
RelativePath=".\NaveNet\NFIOBuffer.h">
</File>
<File
RelativePath=".\NaveNet\NFNet.cpp">
</File>
<File
RelativePath=".\NaveNet\NFNet.h">
</File>
<File
RelativePath=".\NaveNet\NFNetClientS.cpp">
</File>
<File
RelativePath=".\NaveNet\NFNetClientS.h">
</File>
<File
RelativePath=".\NaveNet\NFPacket.cpp">
</File>
<File
RelativePath=".\NaveNet\NFPacket.h">
</File>
<File
RelativePath=".\NaveNet\NFSync.h">
</File>
<Filter
Name="GZip"
Filter="">
<File
RelativePath=".\NaveNet\GZip\adler32.c">
</File>
<File
RelativePath=".\NaveNet\GZip\compress.c">
</File>
<File
RelativePath=".\NaveNet\GZip\crc32.c">
</File>
<File
RelativePath=".\NaveNet\GZip\crc32.h">
</File>
<File
RelativePath=".\NaveNet\GZip\deflate.c">
</File>
<File
RelativePath=".\NaveNet\GZip\deflate.h">
</File>
<File
RelativePath=".\NaveNet\GZip\gzio.c">
</File>
<File
RelativePath=".\NaveNet\GZip\gzip.cpp">
</File>
<File
RelativePath=".\NaveNet\GZip\gzip.h">
</File>
<File
RelativePath=".\NaveNet\GZip\infback.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inffast.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inffast.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inffixed.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inflate.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inflate.h">
</File>
<File
RelativePath=".\NaveNet\GZip\inftrees.c">
</File>
<File
RelativePath=".\NaveNet\GZip\inftrees.h">
</File>
<File
RelativePath=".\NaveNet\GZip\trees.c">
</File>
<File
RelativePath=".\NaveNet\GZip\trees.h">
</File>
<File
RelativePath=".\NaveNet\GZip\uncompr.c">
</File>
<File
RelativePath=".\NaveNet\GZip\zconf.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zconf.in.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zlib.h">
</File>
<File
RelativePath=".\NaveNet\GZip\zutil.c">
</File>
<File
RelativePath=".\NaveNet\GZip\zutil.h">
</File>
</Filter>
</Filter>
<Filter
Name="NaveServer"
Filter="">
<File
RelativePath=".\NaveServer\Global.cpp">
</File>
<File
RelativePath=".\NaveServer\Global.h">
</File>
<File
RelativePath=".\NaveServer\NFConnection.cpp">
</File>
<File
RelativePath=".\NaveServer\NFConnection.h">
</File>
<File
RelativePath=".\NaveServer\NFConnectionManager.cpp">
</File>
<File
RelativePath=".\NaveServer\NFConnectionManager.h">
</File>
<File
RelativePath=".\NaveServer\NFDBComponent.cpp">
</File>
<File
RelativePath=".\NaveServer\NFDBComponent.h">
</File>
<File
RelativePath=".\NaveServer\NFDefine.h">
</File>
<File
RelativePath=".\NaveServer\NFMemPool.h">
</File>
<File
RelativePath=".\NaveServer\NFOLEDB.cpp">
</File>
<File
RelativePath=".\NaveServer\NFOLEDB.h">
</File>
<File
RelativePath=".\NaveServer\NFPacketPool.cpp">
</File>
<File
RelativePath=".\NaveServer\NFPacketPool.h">
</File>
<File
RelativePath=".\NaveServer\NFServerCtrl.cpp">
</File>
<File
RelativePath=".\NaveServer\NFServerCtrl.h">
</File>
<File
RelativePath=".\NaveServer\NFUpdateManager.cpp">
</File>
<File
RelativePath=".\NaveServer\NFUpdateManager.h">
</File>
<File
RelativePath=".\NaveServer\Struct.h">
</File>
<File
RelativePath=".\NaveServer\UICmdEdit.cpp">
</File>
<File
RelativePath=".\NaveServer\UICmdEdit.h">
</File>
<File
RelativePath=".\NaveServer\UICmdMsgView.cpp">
</File>
<File
RelativePath=".\NaveServer\UICmdMsgView.h">
</File>
<File
RelativePath=".\NaveServer\UIFramework.cpp">
</File>
<File
RelativePath=".\NaveServer\UIFramework.h">
</File>
</Filter>
<Filter
Name="MD5"
Filter="">
<File
RelativePath=".\MD5\global.h">
</File>
<File
RelativePath=".\MD5\md5.h">
</File>
<File
RelativePath=".\MD5\md5c.c">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,361 @@
#include "Global.h"
#include "NFIPSec.h"
#include <Nave/NFStringUtil.h>
#include <Nave/NFTokenizer.h>
#include <NaveNet/GZip/zlib.h>
#pragma comment(lib,"zlib.lib")
NFIPSec::NFIPSec(void)
{
}
NFIPSec::~NFIPSec(void)
{
}
void NFIPSec::LoadAllowIP(WCHAR* lpIPFileName)
{
m_vecAllowIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rt");
if(!fp)
return;
char strBuff[256];
IPBAND ip;
while(true)
{
fgets(strBuff, 256, fp);
if(feof(fp))
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecAllowIP.push_back(ip);
}
fclose(fp);
}
void NFIPSec::LoadBlockIP(WCHAR* lpIPFileName)
{
m_vecBlockIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rt");
if(!fp)
return;
char strBuff[256];
IPBAND ip;
while(true)
{
fgets(strBuff, 256, fp);
if(feof(fp))
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecBlockIP.push_back(ip);
}
fclose(fp);
}
BOOL GetLine( const CHAR* sBuf, INT maxsBuf, CHAR* tBuf, INT maxtBuf, LONG& index )
{
ZeroMemory(tBuf, sizeof(tBuf));
INT DestIndex = index;
CHAR* pLine = "\n";
INT pLen = strlen(pLine);
for(INT i = 0; i < maxsBuf; i++)
{
if(index+i >= maxsBuf)
break;
if(strncmp(&sBuf[index+i], pLine, pLen) == 0)
{
CopyMemory(tBuf, sBuf+index, i);
index += (i+pLen);
tBuf[i] = 0;
return TRUE;
}
}
INT len = maxsBuf-index;
if(maxtBuf <= len)
len = maxtBuf-index;
CopyMemory(tBuf, sBuf+index, len);
tBuf[len] = 0;
index += len;
return FALSE;
}
void NFIPSec::LoadAllowIPZ(WCHAR* lpIPFileName)
{
m_vecAllowIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rb");
if(!fp)
return;
long len;
long datalen;
char szMD5[40];
memset(szMD5, 0, sizeof(szMD5));
fread(&len, sizeof(long), 1, fp);
fread(&datalen, sizeof(long), 1, fp);
fread(szMD5, 32, 1, fp);
char* fileDat = new char[datalen];
fread(fileDat, datalen, 1, fp);
fclose(fp);
// MD5를 이용해 암호화를 합니다.
for(long i = 0; i < datalen; ++i)
{
fileDat[i] = fileDat[i]^szMD5[i%32];
}
char* outDat = new char[len*2];
// 파일을 디코딩 합니다.
uLongf destLen;
uncompress((Bytef*)outDat, &destLen, (Bytef*)fileDat, datalen);
outDat[destLen]=0;
if(fileDat)
delete []fileDat;
LONG index = 0;
char strBuff[256];
IPBAND ip;
BOOL bRet = TRUE;
while(bRet)
{
bRet = GetLine(outDat, destLen, strBuff, 256, index);
if(strlen(strBuff) == 0)
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecAllowIP.push_back(ip);
}
if(outDat)
delete []outDat;
}
void NFIPSec::LoadBlockIPZ(WCHAR* lpIPFileName)
{
m_vecBlockIP.clear();
FILE * fp = _wfopen(lpIPFileName, L"rb");
if(!fp)
return;
long len;
long datalen;
char szMD5[40];
memset(szMD5, 0, sizeof(szMD5));
fread(&len, sizeof(long), 1, fp);
fread(&datalen, sizeof(long), 1, fp);
fread(szMD5, 32, 1, fp);
char* fileDat = new char[datalen];
fread(fileDat, datalen, 1, fp);
fclose(fp);
// MD5를 이용해 암호화를 합니다.
for(long i = 0; i < datalen; ++i)
{
fileDat[i] = fileDat[i]^szMD5[i%32];
}
char* outDat = new char[len*2];
// 파일을 디코딩 합니다.
uLongf destLen;
uncompress((Bytef*)outDat, &destLen, (Bytef*)fileDat, datalen);
outDat[destLen]=0;
if(fileDat)
delete []fileDat;
LONG index = 0;
char strBuff[256];
IPBAND ip;
BOOL bRet = TRUE;
while(bRet)
{
bRet = GetLine(outDat, destLen, strBuff, 256, index);
if(strlen(strBuff) == 0)
break;
Nave::NFTokenizerA strtok = Nave::NFTokenizerA(strBuff, "\t");
int cnt = strtok.CountTokens();
ip.start = inet_addr(strtok.NextToken().c_str());
ip.start = htonl(ip.start);
ip.end = inet_addr(strtok.NextToken().c_str());
ip.end = htonl(ip.end );
m_vecBlockIP.push_back(ip);
}
if(outDat)
delete []outDat;
}
BOOL NFIPSec::IsAliveIP(const char * strIP)
{
return IsAliveIP(inet_addr(strIP));
}
BOOL NFIPSec::IsAliveIP(unsigned long dwIP)
{
if(CheckBlockIP(dwIP))
return FALSE;
return CheckAllowIP(dwIP);
}
BOOL NFIPSec::CheckAllowIP(const char * strIP)
{
return CheckAllowIP(inet_addr(strIP));
}
BOOL NFIPSec::CheckAllowIP(unsigned long dwIP)
{
// 바이트를 뒤집어준다.
dwIP = htonl(dwIP);
int iCount = (int)m_vecAllowIP.size();
for(int i = 0; i < iCount; ++i)
{
if(m_vecAllowIP[i].start <= dwIP && dwIP <= m_vecAllowIP[i].end)
return TRUE;
}
return FALSE;
}
BOOL NFIPSec::CheckBlockIP(const char * strIP)
{
return CheckBlockIP(inet_addr(strIP));
}
BOOL NFIPSec::CheckBlockIP(unsigned long dwIP)
{
// 바이트를 뒤집어준다.
dwIP = htonl(dwIP);
int iCount = (int)m_vecBlockIP.size();
for(int i = 0; i < iCount; ++i)
{
if(m_vecBlockIP[i].start <= dwIP && dwIP <= m_vecBlockIP[i].end)
return TRUE;
}
return FALSE;
}
int NFIPSec::SerializeOut(int iType, int iPos, int iCount, char* lpBuffer_Out)
{
LPIPBAND ipOut = (LPIPBAND)lpBuffer_Out;
LPIPBAND ipCur;
int iLast = iPos+iCount;
if(iType == 0)
{
if(m_vecAllowIP.empty())
return 0;
if(iLast >= (int)m_vecAllowIP.size())
{
iLast = (int)m_vecAllowIP.size();
iCount = iLast-iPos;
}
for(int i = iPos; i < iLast; ++i, ++ipOut)
{
ipCur = &m_vecAllowIP[i];
ipOut->start = ipCur->start;
ipOut->end = ipCur->end;
}
return iCount;
}
else if(iType == 1)
{
if(m_vecBlockIP.empty())
return 0;
if(iLast >= (int)m_vecBlockIP.size())
{
iLast = (int)m_vecBlockIP.size();
iCount = iLast-iPos;
}
for(int i = iPos; i < iLast; ++i, ++ipOut)
{
ipCur = &m_vecBlockIP[i];
ipOut->start = ipCur->start;
ipOut->end = ipCur->end;
}
return iCount;
}
return 0;
}
void NFIPSec::SerializeIn(int iType, int iCount, char* lpBuffer_In)
{
LPIPBAND ipIn = (LPIPBAND)lpBuffer_In;
if(iType == 0)
{
for(int i = 0; i < iCount; ++i, ++ipIn)
m_vecAllowIP.push_back(*ipIn);
}
else if(iType == 1)
{
for(int i = 0; i < iCount; ++i, ++ipIn)
m_vecBlockIP.push_back(*ipIn);
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include <vector>
typedef struct IPBAND
{
DWORD start;
DWORD end;
}*LPIPBAND;
class NFIPSec
{
public:
NFIPSec(void);
~NFIPSec(void);
public:
void LoadAllowIP(WCHAR* lpIPFileName);
void LoadBlockIP(WCHAR* lpIPFileName);
void LoadAllowIPZ(WCHAR* lpIPFileName);
void LoadBlockIPZ(WCHAR* lpIPFileName);
int SerializeOut(int iType, int iPos, int iCount, char* lpBuffer_Out);
void SerializeIn(int iType, int iCount, char* lpBuffer_In);
inline void ClearAllowIP() { m_vecAllowIP.clear(); }
inline void ClearBlockIP() { m_vecBlockIP.clear(); }
BOOL IsAliveIP(const char * strIP);
BOOL IsAliveIP(unsigned long dwIP);
BOOL CheckAllowIP(const char * strIP);
BOOL CheckAllowIP(unsigned long dwIP);
BOOL CheckBlockIP(const char * strIP);
BOOL CheckBlockIP(unsigned long dwIP);
inline int GetAllowIPCount() { return (int)m_vecAllowIP.size(); }
inline int GetBlockIPCount() { return (int)m_vecBlockIP.size(); }
private:
std::vector<IPBAND> m_vecAllowIP;
std::vector<IPBAND> m_vecBlockIP;
};

View File

@@ -0,0 +1,100 @@
#include "Nave.h"
#include "NFIni.h"
namespace Nave {
NFIni::NFIni()
{
ZeroMemory(m_szFileName, sizeof(m_szFileName));
}
NFIni::~NFIni()
{
}
BOOL NFIni::Open(LPCWSTR fileName)
{
if (!fileName)
return FALSE;
wcsncpy(m_szFileName, fileName, MAX_PATH);
return TRUE;
}
BOOL NFIni::Close()
{
return TRUE;
}
BOOL NFIni::GetValue(LPCWSTR keyName, LPCWSTR valueName, LPDWORD value)
{
if (!keyName || !valueName || !value)
return FALSE;
*value = GetPrivateProfileIntW(keyName, valueName, 0, m_szFileName);
return TRUE;
}
BOOL NFIni::GetValue(LPCWSTR keyName, LPCWSTR valueName, FLOAT *value)
{
if (!keyName || !valueName || !value)
return FALSE;
WCHAR Value[16] = {0,};
GetPrivateProfileStringW(keyName, valueName, L"", Value, 16, m_szFileName);
*value = (FLOAT)_wtof(Value);
return TRUE;
}
BOOL NFIni::GetValue(LPCWSTR keyName, LPCWSTR valueName, LPWSTR value, DWORD bufferLength)
{
if (!keyName || !valueName || !value || bufferLength == 0)
return FALSE;
GetPrivateProfileStringW(keyName, valueName, L"", value, bufferLength, m_szFileName);
return TRUE;
}
BOOL NFIni::SetValue(LPCWSTR keyName, LPCWSTR valueName, DWORD value)
{
if (!keyName || !valueName)
return FALSE;
WCHAR Value[16] = {0,};
_itow(value, Value, 10);
WritePrivateProfileStringW(keyName, valueName, Value, m_szFileName);
return TRUE;
}
BOOL NFIni::SetValue(LPCWSTR keyName, LPCWSTR valueName, LPCWSTR value)
{
if (!keyName || !valueName || !value)
return FALSE;
WritePrivateProfileStringW(keyName, valueName, value, m_szFileName);
return TRUE;
}
BOOL NFIni::SetValue(LPCWSTR keyName, LPCWSTR valueName, FLOAT value)
{
if (!keyName || !valueName)
return FALSE;
WCHAR Value[16] = {0,};
swprintf(Value, L"%f", value);
WritePrivateProfileStringW(keyName, valueName, Value, m_szFileName);
return TRUE;
}
}

View File

@@ -0,0 +1,103 @@
/**
* @file NFIni.h
* @brief INI 파일 관리자
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
namespace Nave {
/**
* @class NFIni
* @brief INI파일을 사용하기 쉽게 만든 관리 클래스
* @remarks NFIni ini; \r\n
* ini.Open(L"c:\\Init.ini"); \r\n
* ini.SetValue(L"SERVER CONFIG", L"PORT", dwPort); \r\n
* ini.Close(); \r\n
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFIni
{
public:
/// NFIni 생성자
NFIni();
/// NFIni 소멸자
~NFIni();
public:
/**
* @brief INI파일을 오픈합니다.
* @param fileName 파일명
* @return 성공여부
*/
BOOL Open(LPCWSTR fileName);
/**
* @brief INI파일을 종료합니다.
* @return 성공여부
*/
BOOL Close();
/**
* @brief INI파일에 값을 넣습니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 값
* @return 성공여부
*/
BOOL SetValue(LPCWSTR keyName, LPCWSTR valueName, LPCWSTR value);
/**
* @brief INI파일에 값을 넣습니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 값
* @return 성공여부
*/
BOOL SetValue(LPCWSTR keyName, LPCWSTR valueName, DWORD value);
/**
* @brief INI파일에 값을 넣습니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 값
* @return 성공여부
*/
BOOL SetValue(LPCWSTR keyName, LPCWSTR valueName, FLOAT value);
/**
* @brief INI파일에 값을 가져옵니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 저장 버퍼
* @param bufferLength 퍼버의 길이
* @return 성공여부
*/
BOOL GetValue(LPCWSTR keyName, LPCWSTR valueName, LPWSTR value, DWORD bufferLength);
/**
* @brief INI파일에 값을 가져옵니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 저장 버퍼
* @return 성공여부
*/
BOOL GetValue(LPCWSTR keyName, LPCWSTR valueName, LPDWORD value);
/**
* @brief INI파일에 값을 가져옵니다.
* @param keyName Key 이름
* @param valueName Value 이름
* @param value 저장 버퍼
* @return 성공여부
*/
BOOL GetValue(LPCWSTR keyName, LPCWSTR valueName, FLOAT *value);
private:
/// INI 파일명
WCHAR m_szFileName[MAX_PATH];
};
}

View File

@@ -0,0 +1,252 @@
#include "Nave.h"
#include "NFStringUtil.h"
#include <list>
#include "NFLog.h"
namespace Nave {
HWND NFLog::s_hLogHandel = NULL;
BOOL NFLog::s_bEnableLogPrint = TRUE;
BOOL NFLog::s_bSaveLogFile = FALSE;
int NFLog::s_iLogLimit = NFLog::Info;
BOOL NFLog::s_bLogDetail = FALSE;
NFLogManager* NFLog::s_pLogManager = NULL;
// Message를 출력할 윈도우 핸들을 셋팅한다.
void NFLog::SetLogHandel(HWND hListWnd)
{
s_hLogHandel = hListWnd;
}
void NFLog::SetLogPrint(BOOL enable)
{
s_bEnableLogPrint = enable;
}
void NFLog::SetLogOutput(BOOL enable, DWORD dwSize)
{
s_bSaveLogFile = enable;
SetLogPrint(enable);
_DELETE(s_pLogManager);
if(s_bSaveLogFile)
{
s_pLogManager = new NFLogManager();
s_pLogManager->Initialize(FALSE);
s_pLogManager->SetLogMaxSize(dwSize);
}
}
void NFLog::CloseLog()
{
if(s_pLogManager)
{
s_pLogManager->Flush();
_DELETE(s_pLogManager);
}
}
void NFLog::SetLogLimit(int limit)
{
s_iLogLimit=limit;
}
void NFLog::SetLogDetail(BOOL detail)
{
s_bLogDetail = detail;
}
void NFLog::AddLogMsg( HWND hWnd, WCHAR* String, int Len )
{
// 삭제
int iCount = (int)SendMessageW( hWnd, LB_GETCOUNT, 0, 0L )-256;
for(int i = 0; i < iCount; ++i)
SendMessageW( hWnd, LB_DELETESTRING, 0, 0L );
// 추가
WCHAR* p;
int k;
p = String;
int iAdd = 0;
k = 0;
while( k++ < Len )
{
switch( *String )
{
case L'\n':
*String = 0;
++iAdd;
SendMessageW( hWnd, LB_ADDSTRING, 0, (LPARAM)(LPWSTR)p );
p = ++String;
break;
default :
++String;
}
}
if( *p )
{
++iAdd;
SendMessageW( hWnd, LB_ADDSTRING, 0, (LPARAM)(LPWSTR)p );
}
int Top = (int)SendMessageW( hWnd, LB_GETTOPINDEX, 0, 0L );
SendMessageW( hWnd, LB_SETTOPINDEX, Top+iAdd, 0L );
}
void NFLog::LogPrintf( WCHAR* msg, ... )
{
va_list v;
WCHAR buf[1024];
int len;
va_start( v, msg );
len = vswprintf( buf, msg, v );
va_end( v );
LogPrintf( Info, buf);
}
void NFLog::OutputLog(const WCHAR* log)
{
static CHAR stDot[4] = "\r\n";
static CHAR stTime[32];
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
sprintf(stTime, "[%04d.%02d.%02d-%02d:%02d:%02d]", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
Nave::StringA str = stTime;
str += ToASCII(log);
str += stDot;
int iSize = str.size();
char* pPoint = s_pLogManager->ReserveBuffer(iSize);
memcpy(pPoint, str.c_str(), iSize);
}
void NFLog::LogPrintf( int group, WCHAR* msg )
{
if (group < s_iLogLimit)
return;
if(s_bEnableLogPrint)
{
if(s_hLogHandel == NULL)
{
// setlocale 함수를 지정해야 한글이 출력됨
wprintf(msg);
wprintf(L"\n");
}
else
AddLogMsg( s_hLogHandel, msg, (int)wcslen(msg) );
}
#ifdef _DEBUG
OutputDebugStringW( msg );
OutputDebugStringW( L"\r\n" );
#endif
if(s_bSaveLogFile)
{
Nave::StringW tmp = msg;
Nave::StringW logmsg;
switch (group) {
case Info:
logmsg=L"[INF] " + tmp;
break;
case Warning:
logmsg=L"[WAR] " + tmp;
break;
case Error:
logmsg=L"[ERR] " + tmp;
break;
case Exception:
logmsg=L"[EXP] " + tmp;
break;
case Important:
logmsg=L"[DET] " + tmp;
break;
};
OutputLog(logmsg.c_str());
}
}
void NFLog::LogPrintf( int group, const WCHAR* pFile, int pLinenum, const WCHAR* pFunc, WCHAR* msg )
{
if (group < s_iLogLimit)
return;
if(s_bEnableLogPrint)
{
if(s_hLogHandel == NULL)
{
wprintf(msg);
wprintf(L"\n");
}
else
AddLogMsg( s_hLogHandel, msg, (int)wcslen(msg) );
}
#ifdef _DEBUG
OutputDebugStringW( msg );
OutputDebugStringW( L"\r\n" );
#endif
if(s_bSaveLogFile)
{
Nave::StringW tmp = msg;
Nave::StringW logmsg;
switch (group) {
case Info:
logmsg=L"[INF]" + tmp;
break;
case Warning:
logmsg=L"[WAR]" + tmp;
break;
case Error:
logmsg=L"[ERR]" + tmp;
break;
case Exception:
logmsg=L"[EXP]" + tmp;
break;
case Important:
logmsg=L"[DET]" + tmp;
break;
};
OutputLog(logmsg.c_str());
static WCHAR deta[1024];
swprintf(deta, L" -> [%s,%d,%s]", pFile, pLinenum, pFunc);
OutputLog(deta);
}
}
NFLog::Proxy::Proxy(int pGroup, const WCHAR* pFile, int pLinenum, const WCHAR* pFunc) : file(pFile),linenum(pLinenum), func(pFunc), group(pGroup)
{
}
void NFLog::Proxy::Log(const WCHAR* msg, ...)
{
if (group < NFLog::s_iLogLimit)
return;
WCHAR txt[1024];
va_list l;
va_start(l,msg);
_vsnwprintf( txt, 1024, msg, l );
va_end(l);
if(!NFLog::s_bLogDetail)
LogPrintf(group,txt);
else
LogPrintf(group,file,linenum,func,txt); // 이건 파일과 기타 정보를 남길때..
}
}

View File

@@ -0,0 +1,142 @@
/**
* @file NFLog.h
* @brief Log 출력 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include "NFLogManager.h"
namespace Nave {
/**
* @class NFLog
* @brief Log 출력 클래스
* @remarks NFLog::SetLogHandel(hList); // 특정 윈도우로 로그를 출력한다. \r\n
* NFLog::EnableLogPrint(TRUE); // 로그를 화면에 출력한다. \r\n
* NFLog::EnableLogOutput(TRUE); // 로그를 파일로 저장한다 \r\n
* NFLog::SetLogDetail(TRUE); // 상세 로그로 설정합니다. \r\n
* NFLog::SetLogLimit(NFLog::Proxy::Info) // 로그 리미터를 정의합니다. \r\n
* // 로그 사용 \r\n
* LOG_IMPORTANT((L"Test Start")); \r\n
* // 로그를 마무리합니다. \r\n
* NFLog::CloseLog(); \r\n
* @warning NFLog::CloseLog()를 호출하지 않을경우 파일로 로그가 저장되지
* 않습니다.
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFLog
{
public:
/// 각 로그의 Index 타입
enum Groups {
Info = 1 << 0,
Warning = 1 << 1,
Error = 1 << 2,
Exception = 1 << 3,
Important = 1 << 4,
};
/// 로그 출력용 구조체
struct Proxy
{
/// 로그가 호출된 함수
const WCHAR* func;
/// 로그가 호출된 파일
const WCHAR* file;
/// 로그가 호출된 라인번호
int linenum;
/// 로그의 그룹아이디
int group;
Proxy(int pGroup, const WCHAR* pFile, int pLinenum, const WCHAR* pFunc);
void Log(const WCHAR* msg, ...);
};
/// Message를 출력할 윈도우 핸들을 셋팅한다.
static void SetLogHandel(HWND hListWnd);
/// 화면에 로고를 찍을꺼냐
static void SetLogPrint(BOOL enable = TRUE);
/// 파일로 로그를 찍을꺼냐
static void SetLogOutput(BOOL enable = TRUE, DWORD dwSize = 100 * 1024 * 1024);
/// 로그의 사용 리미터를 정의합니다. NFLog::Info ~ NFLog::Important
static void SetLogLimit(int limit);
/// 상세 로그를 남깁니다.
static void SetLogDetail(BOOL detail);
/// 로그를 종료합니다. (임시변수에 저장된 로그를 파일로 저장합니다.)
static void CloseLog();
private:
/**
* @brief hWnd에 String을 출력한다.
* @param hWnd 윈도우 핸들
* @param String 메시지
* @param Len 메시지길이
*/
static void AddLogMsg( HWND hWnd, WCHAR* String, int Len );
/**
* @brief 메시지를 출력한다. 콘솔일때 printf로 윈도우모드일때 Msg윈도우로 출력
* @param *msg 출력 메시지
* @param ... 인자
*/
static void LogPrintf( WCHAR* msg, ... );
/**
* @brief 메시지를 출력한다. 콘솔일때 printf로 윈도우모드일때 Msg윈도우로 출력
* @param group 그룹인덱스
* @param *msg 메시지
*/
static void LogPrintf( int group, WCHAR* msg );
/**
* @brief 메시지를 출력한다. 콘솔일때 printf로 윈도우모드일때 Msg윈도우로 출력
* @param group 그룹인덱스
* @param pFile 호출파일명
* @param pLinenum 호출라인
* @param pFunc 호출함수
* @param *msg 메시지
*/
static void LogPrintf( int group, const WCHAR* pFile, int pLinenum, const WCHAR* pFunc, WCHAR* msg );
/// 로그 문자열을 추가합니다.
static void OutputLog(const WCHAR* log);
private:
/// Message를 출력할 윈도우 핸들
static HWND s_hLogHandel;
/// 로그출력을 활성화 합니다.
static BOOL s_bEnableLogPrint;
/// 로그를 파일로 저장합니다.
static BOOL s_bSaveLogFile;
/// 로그 Limit
static int s_iLogLimit;
/// 로그 Detail
static BOOL s_bLogDetail;
/// 로그를 파일을 관리하는 매니져
static NFLogManager* s_pLogManager;
};
}
/// Info Log
#define LOG_INFO(LOGMESSAGE) {Nave::NFLog::Proxy(Nave::NFLog::Info, __WFILE__, __LINE__,__WFUNCSIG__).Log LOGMESSAGE;}
/// Warning Log
#define LOG_WARNING(LOGMESSAGE) {Nave::NFLog::Proxy(Nave::NFLog::Warning,__WFILE__, __LINE__,__WFUNCSIG__).Log LOGMESSAGE;}
/// Error Log
#define LOG_ERROR(LOGMESSAGE) {Nave::NFLog::Proxy(Nave::NFLog::Error,__WFILE__, __LINE__,__WFUNCSIG__).Log LOGMESSAGE;}
/// Exeption Log
#define LOG_EXCEPTION(LOGMESSAGE) {Nave::NFLog::Proxy(Nave::NFLog::Exception,__WFILE__, __LINE__,__WFUNCSIG__).Log LOGMESSAGE;}
/// Important Log
#define LOG_IMPORTANT(LOGMESSAGE) {Nave::NFLog::Proxy(Nave::NFLog::Important,__WFILE__, __LINE__,__WFUNCSIG__).Log LOGMESSAGE;}

View File

@@ -0,0 +1,348 @@
#include "Nave.h"
#include "NFLog.h"
#include "NFLogManager.h"
#include "NFThreadManager.h"
namespace Nave {
NFLogThread::NFLogThread() : m_pLogHandle(NULL), m_bCompress(TRUE),
m_hFlush(CreateEvent(0, TRUE, FALSE, 0)),
m_hFile(INVALID_HANDLE_VALUE), m_dwTotalWritten(0),
m_dwMaxFileSize(MAX_FILE_SIZE)
{
InterlockedExchange(&m_bEnd, FALSE);
}
NFLogThread::~NFLogThread()
{
if(INVALID_HANDLE_VALUE != m_hFile)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
if(0 != m_hFlush)
{
CloseHandle(m_hFlush);
m_hFlush = 0;
}
}
VOID NFLogThread::Initialize(NFLogManager* pLog, BOOL bCompress)
{
m_bCompress = bCompress;
m_pLogHandle = pLog;
}
unsigned int NFLogThread::Run()
{
// 여기서 m_bEnd가 TRUE가 아니면 스레드가 작동하고 있다.
for(;TRUE != InterlockedCompareExchange(&m_bEnd, TRUE, TRUE);)
{
// 현재 이벤트가 사용중이면 1초간 대기후 다시 확인.
if(WAIT_TIMEOUT == WaitForSingleObject(m_hFlush, 1000))
{
continue;
}
WriteLog();
};
WriteLog();
return 0;
}
BOOL NFLogThread::End()
{
InterlockedExchange(&m_bEnd, TRUE);
SetEvent(m_hFlush);
return TRUE;
}
BOOL NFLogThread::WriteLog()
{
// 로그에서 버퍼를 읽어온다.
if(!m_pLogHandle)
return FALSE;
m_pLogHandle->SpliceInWriteBuffer(m_WriteBufferList);
if(m_WriteBufferList.empty())
return TRUE;
if(INVALID_HANDLE_VALUE == m_hFile)
{
SetLogFileName();
m_hFile = CreateFileW(m_szLogFileName, GENERIC_WRITE,
FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(INVALID_HANDLE_VALUE == m_hFile)
{
return FALSE;
}
}
unsigned long dwWritten = 0;
for(NFLogBuffer::List::iterator itr = m_WriteBufferList.begin();
itr != m_WriteBufferList.end(); ++itr)
{
NFLogBuffer* pLogBuffer = *itr;
if(FALSE == WriteFile(m_hFile, pLogBuffer->m_Buffer, pLogBuffer->m_dwUsage, &dwWritten, 0))
{
LOG_ERROR((L"로그 파일 기록에 실패했습니다. ErrorNum : %d, FileHandle:0x%p, 버퍼 크기:%d",
GetLastError(), m_hFile, pLogBuffer->m_dwUsage));
}
m_dwTotalWritten += dwWritten;
}
m_pLogHandle->SpliceInFreeBuffer(m_WriteBufferList);
// 파일은 계속 열어놓는다.
if(m_dwTotalWritten > m_dwMaxFileSize)
{
if(INVALID_HANDLE_VALUE != m_hFile) { CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; } // 파일 닫고...
m_dwTotalWritten = 0;
}
return TRUE;
}
BOOL NFLogThread::SetLogFileName()
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
unsigned long dwSpinCount = 0;
WCHAR szProgramName[MAX_PATH];
WCHAR szLogFilePrefix[MAX_PATH];
// 프로그램이름과 동일한 하위폴더를 생성한다.
Nave::GetProgramName(szProgramName, MAX_PATH);
if(m_pLogHandle)
_snwprintf(szLogFilePrefix, MAX_PATH - 1, L"%s", m_pLogHandle->GetLogFilePrefix());
else
wcsncpy(szLogFilePrefix, szProgramName, MAX_PATH);
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(szProgramName))
{
if (!CreateDirectoryW(szProgramName, 0))
{
return FALSE;
}
}
while (TRUE)
{
int LogLen = _snwprintf(m_szLogFileName, MAX_PATH,
L"%s\\%s-%04d%02d%02d-%02d%02d%02d-%04d.log",
szProgramName, szLogFilePrefix, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, dwSpinCount);
if(LogLen <= 0)
{
LOG_ERROR((L"상세 로그를 위한 파일 이름을 생성할 수 없습니다."));
return FALSE;
}
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(m_szLogFileName))
{
break;
}
++dwSpinCount;
}
return TRUE;
}
NFLogManager::NFLogManager(void) : m_lpDetailBuffer(0)
{
}
NFLogManager::~NFLogManager(void)
{
Destroy();
}
BOOL NFLogManager::Initialize(BOOL bCompress, const WCHAR* szLogFilePrefix)
{
WCHAR strName[MAX_PATH];
Nave::GetProgramName(strName, MAX_PATH);
wcsncpy(m_szLogFilePrefix, strName, MAX_PATH);
if(szLogFilePrefix != 0)
{
wcscat(m_szLogFilePrefix, szLogFilePrefix);
}
// 처음에 프리버퍼 개수만큼 만든다.
for(int nCount = 0; nCount < DEFAULT_FREE_LOG_BUFFER_NUM; ++nCount)
{
NFLogBuffer* pDetailBuffer = new NFLogBuffer;
if(0 == pDetailBuffer)
{
LOG_ERROR((L"상세 로그 버퍼를 할당하는 데 실패했습니다"));
Destroy();
return FALSE;
}
m_FreeList.push_back(pDetailBuffer);
};
// 버퍼가 없으니 우선 1개 가져옴.
if(m_lpDetailBuffer == 0)
{
m_lpDetailBuffer = GetBuffer();
}
m_LogSaveThread.Initialize(this, bCompress);
if(INVALID_HANDLE_VALUE == NFThreadManager::Run(&m_LogSaveThread))
{
LOG_ERROR((L"Flush스레드를 생성하는 데 실패했습니다"));
return FALSE;
}
return TRUE;
}
BOOL NFLogManager::Destroy()
{
Flush();
NFThreadManager::Stop(&m_LogSaveThread, INFINITE);
// 싱크건다.
NFSyncLock CL(&m_LogSync);
NFLogBuffer* pDetailBuffer;
for(NFLogBuffer::List::iterator itr = m_FreeList.begin(); itr != m_FreeList.end(); ++itr)
{
pDetailBuffer = (*itr);
_DELETE(pDetailBuffer);
}
m_FreeList.clear();
for(NFLogBuffer::List::iterator itr = m_WriteList.begin(); itr != m_WriteList.end(); ++itr)
{
pDetailBuffer = (*itr);
_DELETE(pDetailBuffer);
}
m_WriteList.clear();
return TRUE;
}
VOID NFLogManager::SetLogMaxSize(DWORD dwSize)
{
m_LogSaveThread.SetLogMaxSize(dwSize);
}
NFLogBuffer* NFLogManager::GetBuffer()
{
// 싱크건다.
NFSyncLock CL(&m_LogSync);
NFLogBuffer* pLogBuffer = 0;
if(m_FreeList.empty())
{
// 남는 버퍼가 없으면 실시간으로 생성해버린다. 어쩔수없다.
pLogBuffer = new NFLogBuffer;
}
else
{
pLogBuffer = m_FreeList.front();
m_FreeList.pop_front();
}
if(0 == pLogBuffer)
{
LOG_ERROR((L"상세 로그 버퍼를 할당할 수 없습니다."));
return 0;
}
pLogBuffer->Initialize();
return pLogBuffer;
};
BOOL NFLogManager::Flush()
{
// 버퍼를 넣는다.
PushBuffer(&m_lpDetailBuffer);
return m_LogSaveThread.FlushSignal();
}
char* NFLogManager::ReserveBuffer(unsigned short usReserve)
{
NFSyncLock CL(&m_LogSync);
if(0 == m_lpDetailBuffer)
{
m_lpDetailBuffer = GetBuffer();
}
if(NFLogBuffer::MAX_LOG_BUFFER < m_lpDetailBuffer->m_dwUsage + usReserve)
{
Flush(); // 버퍼가 꽉찼으니 저장해라.
m_lpDetailBuffer = GetBuffer();
}
if(0 == m_lpDetailBuffer)
{
LOG_ERROR((L"로그 버퍼가 0입니다."));
return 0;
}
// 컴플리트를 먼저해서 해당영역을 확보한다.
char* pPoint = &m_lpDetailBuffer->m_Buffer[m_lpDetailBuffer->m_dwUsage];
Complete(usReserve);
return pPoint;
}
VOID NFLogManager::SpliceInWriteBuffer(NFLogBuffer::List& logBufferList)
{
NFSyncLock CL(&m_LogSync);
if(m_WriteList.empty())
return;
// WriteBuffer 를 가져온다.
logBufferList.splice(logBufferList.end(), m_WriteList);
}
VOID NFLogManager::SpliceInFreeBuffer(NFLogBuffer::List& logBufferList)
{
NFSyncLock CL(&m_LogSync);
if(logBufferList.empty())
return;
m_FreeList.splice(m_FreeList.end(), logBufferList);
}
VOID NFLogManager::PushBuffer(NFLogBuffer** ppDetailBuffer)
{
if(0 == *ppDetailBuffer) { return; }
NFSyncLock CL(&m_LogSync);
if(0 == (*ppDetailBuffer)->m_dwUsage)
{
// 사이즈가 0이니 다시 Free에 넣음.
m_FreeList.push_back(*ppDetailBuffer);
}
else
{
m_WriteList.push_back(*ppDetailBuffer);
}
// 이부분 대문에 이중포인터로 변수를 받은것.
*ppDetailBuffer = 0;
}
}

View File

@@ -0,0 +1,241 @@
/**
* @file NFLogManager.h
* @brief LogManager 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include <time.h>
#include <list>
#include "NFSync.h"
#include "NFThread.h"
namespace Nave {
class NFLogManager;
/**
* @class NFLogBuffer
* @brief 로그가 저장되는 로그 버퍼 이게 파일로 저장된다.
* @remarks
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFLogBuffer
{
public:
/// Write, Free 버퍼를 리스트로 관리하게 되는데 typedef를 여기서 했다.
typedef std::list<NFLogBuffer*> List;
enum
{
MAX_LOG_BUFFER = 65536 /// 로그버퍼의 크기
};
/// 사용된 버퍼의 사이즈
unsigned long m_dwUsage;
/// 실제 버퍼
char m_Buffer[MAX_LOG_BUFFER];
/// NFLogBuffer 생성자
NFLogBuffer() : m_dwUsage(0)
{
}
/// 초기화 함수
VOID Initialize()
{
m_dwUsage = 0;
}
};
/**
* @class NFLogThread
* @brief 로그를 관리하는 로그 스레드이다. 로그매니져에서 사용됨.
* @remarks
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFLogThread : public NFThread
{
public:
/// NFLogThread 생성자
NFLogThread();
/// NFLogThread 소멸자
~NFLogThread();
/**
* @brief 로그를 초기화한다.
* @param pLog 로그메니져 객체
* @param bCompress 압축여부
*/
VOID Initialize(NFLogManager* pLog, BOOL bCompress);
/**
* @brief 로그파일의 크기를 조절한다. 이크기가 되면 다른 파일로 로그를남긴다.
* @param dwSize 로그파일의 크기 byte 수로 남긴다 10 * 1024 * 1024 는 10메가
*/
inline VOID SetLogMaxSize(DWORD dwSize = MAX_FILE_SIZE) { m_dwMaxFileSize = dwSize; }
/// 로그를 저장한다.
BOOL FlushSignal() { return PulseEvent(m_hFlush); }
/// 로그 스레드를 실행한다.
virtual unsigned int Run();
/// 로그 스레드를 종료합니다.
virtual BOOL End();
private:
enum
{
MAX_FILE_SIZE = 100 * 1024 * 1024 /// 기본 파일 사이즈 100메가
};
/**
* @brief 로그파일의 이름을 설정합니다.
* @return 성공여부
*/
BOOL SetLogFileName();
/**
* @brief 로그버퍼에 로그를 Write 합니다.
* @return 성공여부
*/
BOOL WriteLog();
private:
/// 해당 스레드가 종료됬는지 보는로직
volatile LONG m_bEnd;
/// 현재 해당 스레드가 작동중인지 확인하는 이벤트
HANDLE m_hFlush;
/// 로그가 저장되는 파일핸들
HANDLE m_hFile;
/// 사용된 파일크기
DWORD m_dwTotalWritten;
/// 로그 메니져
NFLogManager* m_pLogHandle;
/// 압축 유무
BOOL m_bCompress;
/// 쓰기 로그 버퍼
NFLogBuffer::List m_WriteBufferList;
/// 로그의 파일이름
WCHAR m_szLogFileName[MAX_PATH];
/// 로그파일의 최대 크기
DWORD m_dwMaxFileSize;
};
/**
* @class NFLogManager
* @brief 로그를 저장할때 사용하는 로그 매니져 클래스
* @remarks 로그 매니져는 한 어플이 여러개의 로그를 종류별로 출력할 수도 있기 때문에 싱글톤으로 만들지 않는다.\r\n
* 디테일로그는 바이너리리를 넣기위해 존재하는 로그다. \r\n
* 안에 들어가는 로그는 게임 별로 해당 로그 구조체등을 구현해야한다. \r\n
* 디테일 로그의 경우 속도증가를 위해 처음엔 메모리상에 버퍼를 적고 버퍼가 꽉 찼으면 해당 버퍼를 \r\n
* WriteList에 넣은후 해당 버퍼를 처리한다. \r\n
*
* @par
* @author Edith
* @date 2009-04-04
*/
class NFLogManager
{
public:
/// NFLogManager 생성자
NFLogManager(void);
/// NFLogManager 소멸자
~NFLogManager(void);
/**
* @brief 로그 메니져를 초기화 합니다.
* @param bCompress 압축유무
* @param szLogFilePrefix 로그파일명
* @return 성공여부
*/
BOOL Initialize(BOOL bCompress, const WCHAR* szLogFilePrefix = 0);
/// 로그매니져를 종료합니다.
BOOL Destroy();
/// 로그버퍼의 사이즈를 조절한다.
VOID SetLogMaxSize(DWORD dwSize = 10 * 1024 * 1024);
/**
* @brief 로그파일의 이름
* @return 로그파일이름
*/
const WCHAR* GetLogFilePrefix() const { return m_szLogFilePrefix; }
/**
* @brief 로그를 저장합니다.
* @return 성공여부
*/
BOOL Flush();
/**
* @brief 현재 사용되는 로그 버퍼를 구합니다.
* @return 로그버퍼
*/
NFLogBuffer* GetBuffer();
/**
* @brief 로그버퍼를 할당한다.
* @param usReserve 할당 사이즈
* @return 로그버퍼의 위치포인터
*/
char* ReserveBuffer(unsigned short usReserve);
/**
* @brief 할당된 로그버퍼를 적용시킵니다.
* @param usRealUse 사이즈
*/
VOID Complete(unsigned short usRealUse) { m_lpDetailBuffer->m_dwUsage += usRealUse; }
/**
* @brief 출력상태로 로그버퍼를 할당합니다.
* @param ppDetailBuffer
*/
VOID PushBuffer(NFLogBuffer** ppDetailBuffer);
VOID SpliceInWriteBuffer(NFLogBuffer::List& logBufferList);
VOID SpliceInFreeBuffer(NFLogBuffer::List& logBufferList);
private:
enum
{
DEFAULT_FREE_LOG_BUFFER_NUM = 10 /// 최대 10개까지 프리버퍼를 생성한다.
};
/// Sync 객체
NFSync m_LogSync;
/// 로그 파일명
WCHAR m_szLogFilePrefix[MAX_PATH];
/// 로그 저장용 스레드 변수
NFLogThread m_LogSaveThread;
/// 비어있는 버퍼
NFLogBuffer::List m_FreeList;
/// 파일에 쓰여질 버퍼
NFLogBuffer::List m_WriteList;
/// 현재 사용되는 버퍼
NFLogBuffer* m_lpDetailBuffer;
};
}

View File

@@ -0,0 +1,128 @@
/**
* @file NFSingleton.h
* @brief 싱글톤 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <windows.h>
#include <stdio.h>
#include <assert.h>
/*
#include "NFSingleton.h"
class Test : public Nave::NFSingleton<Test>
{
public:
Test()
{
printf("Test::Test()\n");
}
~Test()
{
printf("Test::~Test()\n");
}
int GetType()
{
return 0;
}
};
INT _tmain(INT argc, WCHAR* argv[])
{
// 만약 싱글톤 객체를 사용하려면
// 아래와 같이 사용하기 위해서 한번 New를 하고
Test* pTest = new Test;
// 다른 위치의 다른함수.
Test::GetInstance().GetType(); 와 같이 사용하면 된다.
delete pTest;
}
*/
#pragma warning (disable : 4311)
#pragma warning (disable : 4312)
namespace Nave {
/**
* @class NFSingleton
* @brief 클래스 객체를 싱글톤으로 생성합니다.
* @remarks
*
* @warning 해당 싱글톤 객체는 처음 생성은 직접 new로 생성을 해주고 \r\n
* delete가 될때까지 싱글톤 같이 사용하며 프로그램이 종료될때\r\n
* delete를 해주면 된다.
* @par
* @author Edith
* @date 2009-04-05
*/
template <typename T> class NFSingleton
{
public:
/// NFSingleton 생성자
NFSingleton (void)
{
assert( !s_pSingleton && "NFSingleton : You can't create more"
" object, because this object is SINGLETON.");
#if defined( _MSC_VER ) && _MSC_VER < 1200
int iOffset = (int)(T*)1 - (int)(NFSingleton <T>*)(T*)1;
s_pSingleton = (T*)((int) this + iOffset);
#else
s_pSingleton = static_cast< T* >( this );
#endif
}
/// NFSingleton 소멸자
~NFSingleton (void)
{
assert( s_pSingleton && "NFSingleton : This object may be "
"destroyed by someone's memory control or other causes.");
s_pSingleton = 0;
}
/// 해당 싱글톤 객체가 생성되는지 확인한다.
static bool IsAlive()
{
return s_pSingleton ? true : false;
}
/// 싱글톤 객체의 인스턴스를 얻는다.
static T& GetInstance(void)
{
assert (s_pSingleton && "NFSingleton : Something is wrong."
" This object destroyed by something bad method or"
"you didn't create yet!");
return *s_pSingleton;
}
/// 싱글톤 객체의 유일한 인스턴스의 포인터를 얻는다
static T* GetInstancePtr(void)
{
assert (s_pSingleton && "NFSingleton : Something is wrong."
" This object destroyed by something bad method.");
return s_pSingleton;
}
private:
/// 싱글톤 객체를 담을 객체의 포인터
static T* s_pSingleton;
};
/// 싱글톤 객체 변수를 초기화 한다.
template<typename T> T* NFSingleton<T>::s_pSingleton = 0;
}

View File

@@ -0,0 +1,45 @@
/**
* @file NFStringCompare.h
* @brief ¹®ÀÚ¿­ Compare Ŭ·¡½º
* @remarks
* @author °­µ¿¸í(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
namespace Nave {
template <typename fc> inline BOOL Compare(fc i1,const fc& iend1,fc i2,const fc& iend2) {
for (;(i1 != iend1) && ( i2 != iend2); ++i1, ++i2) {
if ((*i1) != (*i2)) return FALSE;
}
if ( (i1 == iend1) && ( i2 == iend2)) return TRUE;
return FALSE;
}
template <typename fc> inline BOOL Compare(std::pair<fc,fc>& a, std::pair<fc,fc>& b) {
Compare(a.first,a.second,b.first,b.second);
}
inline BOOL Compare(std::string::const_iterator i1,const std::string::const_iterator& iend1, const char* i2) {
for (;(i1 != iend1) && ( *i2 != 0); ++i1, ++i2) {
if ((*i1) != (*i2)) return FALSE;
}
if ( (i1 == iend1) && ( *i2 == 0)) return TRUE;
return FALSE;
}
inline BOOL Compare(std::wstring::const_iterator i1,const std::wstring::const_iterator& iend1, const wchar_t* i2) {
for (;(i1 != iend1) && ( *i2 != 0); ++i1, ++i2) {
if ((*i1) != (*i2)) return FALSE;
}
if ( (i1 == iend1) && ( *i2 == 0)) return TRUE;
return FALSE;
}
inline BOOL Compare(const std::pair<std::string::const_iterator,std::string::const_iterator>& a, const char* b) {
return Compare(a.first,a.second,b);
}
}

View File

@@ -0,0 +1,54 @@
#include "NFStringUtil.h"
namespace Nave {
std::string Format(char* format, ...) {
static char txt[1024];
va_list l;
va_start(l,format);
_vsnprintf( txt, 1024, format, l );
va_end(l);
return txt;
}
std::wstring Format(wchar_t* format, ...) {
static wchar_t txt[1024];
va_list l;
va_start(l,format);
_vsnwprintf( txt, 1024, format, l );
va_end(l);
return txt;
}
std::wstring RemoveDots(const std::wstring& str2)
{
std::wstring str=str2;
// balal/rear/../reareako.txt
size_t pos1=str.find(L"/..");
while ( pos1 != std::wstring::npos)
{
BOOL found = FALSE;
for ( int i=int(pos1)-1; i >= 0; --i)
{
if ( str[i] == L'/' )
{
str=str.substr(0,i)+str.substr(pos1+3);
found=TRUE;
break;
}
}
if (!found)
{
str=str.substr(pos1+3);
}
pos1=str.find(L"/..");
}
return str;
}
}

View File

@@ -0,0 +1,126 @@
/**
* @file NFStringGeneral.h
* @brief 문자열 파싱 및 생성클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <string>
namespace Nave {
inline std::pair<const wchar_t*, const wchar_t*> Split(const wchar_t* ibegin,const wchar_t* iend, wchar_t delimiter) {
for ( const wchar_t* i=ibegin; i != iend; ++i) {
if ( (*i) == delimiter ) {
if (i == ibegin) {
++ibegin;
continue;
}
return std::pair<const wchar_t*,const wchar_t*>(ibegin,i);
}
}
return std::pair<const wchar_t*,const wchar_t*>(ibegin,iend);
}
template <typename fc> inline std::pair<fc, fc> Split(fc ibegin,const fc& iend, typename fc::value_type delimiter) {
for ( fc i=ibegin; i != iend; ++i) {
if ( (*i) == delimiter ) {
if (i == ibegin) {
++ibegin;
continue;
}
return std::pair<fc,fc>(ibegin,i);
}
}
return std::pair<fc,fc>(ibegin,iend);
}
template <typename iterator, typename container> void
Split(iterator ibegin, const iterator& iend, typename iterator::value_type delimiter,
container& result)
{
std::pair<iterator, iterator> p(ibegin, ibegin);
while(p.second!=iend)
{
p=Split(p.first, iend, delimiter);
container::value_type str(p.first, p.second);
result.push_back(str);
p.first=p.second;
}
}
inline void LeftTrim(std::string& s) { s.erase(0, s.find_first_not_of(" ")); }
inline void LeftTrim(std::wstring& s) { s.erase(0, s.find_first_not_of(L" ")); }
inline void RightTrim(std::string& s) { s.resize(s.find_last_not_of(" ") + 1); }
inline void RightTrim(std::wstring& s) { s.resize(s.find_last_not_of(L" ") + 1); }
template <typename fc > inline void Trim(fc& s)
{
LeftTrim(s);
RightTrim(s);
}
std::string Format(char* format, ...);
std::wstring Format(wchar_t* format, ...);
std::string PositionalFormat(char* format, ...);
std::wstring PositionalFormat(wchar_t* format, ...);
template <typename fc> inline fc ParseFileNameNoPath(const fc& str) {
fc tmp=ParseFileName(str);
fc::size_type pos = tmp.find_last_of(L"\\/:");
if (pos != std::wstring::npos)
return tmp.substr(pos+1);
return tmp;
}
/**
Extract filename, "filename|itemname" -> filename
file name includes path
"c:\data\bla|something" -> "c:\data\bla"
*/
template <typename fc> inline fc ParseFileName(const fc& str) {
std::pair<typename fc::const_iterator,typename fc::const_iterator> pair=Split(str.begin(),str.end(),L'|');
return fc(pair.first, pair.second);
}
/**
extracts the item name "filename|itenmae" -> itenname
"c:\data\blabla.xml\hellsemething" -> "something"
*/
template <typename fc> inline fc ParseItemName(const fc& str) {
std::pair<typename fc::const_iterator,typename fc::const_iterator> pair=Split(str.begin(),str.end(),L'|');
if ( pair.second == str.end() ) return fc();
return fc(++pair.second, str.end());
}
/**
"c:\data\blabla.xml\hellsemething" -> "c:\data"
*/
inline std::wstring ParseFilePath(const std::wstring& str) {
std::wstring::size_type pos = str.find_last_of(L"\\/:");
if (pos != std::wstring::npos)
return str.substr(0,pos);
return str;
}
std::wstring RemoveDots(const std::wstring& str2);
}

View File

@@ -0,0 +1,547 @@
#include <windows.h>
#include <stdlib.h>
#include <string>
#include "NFStringGenericConversion.h"
namespace Nave {
unsigned int Hash(const WCHAR* str)
{
//wchar_t* p=const_cast<wchar_t*>(str); <--
//replaced this, we shouldnt be doing const_cast's for no reason @juhnu
const WCHAR* p=str;
unsigned int hashcode=0;
wchar_t c=0;
while(*p)
{
c=*p; hashcode=(31*hashcode+(c%31))%64000000; ++p;
}
return hashcode;
}
unsigned int Hash(const CHAR* str)
{
//wchar_t* p=const_cast<wchar_t*>(str); <--
//replaced this, we shouldnt be doing const_cast's for no reason @juhnu
const CHAR* p=str;
unsigned int hashcode=0;
wchar_t c=0;
while(*p)
{
c=*p;
hashcode=(31*hashcode+(c%31))%64000000; ++p;
}
return hashcode;
}
template<> std::string To(const wchar_t* wstr) {
//int iWstrSize = (int)wcslen(wstr);
int iSize = WideCharToMultiByte(CP_ACP,0,wstr,-1,NULL,0,NULL,NULL);
std::string str(iSize -1, 0);
::WideCharToMultiByte(CP_ACP, 0, wstr, -1, &str[0], iSize, NULL, NULL);
return str;
}
template<> std::wstring To(const wchar_t* wstr) {
//int iWstrSize = (int)wcslen(wstr);
std::wstring tstr(wstr);
return tstr;
}
template <> std::string To(const wstringIteratorPair& StrPair) {
//int iWstrSize = (int)(StrPair.second - StrPair.first);
int iSize = WideCharToMultiByte(CP_ACP,0,&(*StrPair.first), -1 ,NULL,0,NULL,NULL);
//int iSize = (int)(StrPair.second - StrPair.first);
std::string str(iSize -1, 0);
::WideCharToMultiByte(CP_ACP, 0, &(*StrPair.first), -1, &str[0], iSize, NULL, NULL);
return str;
}
template<> std::string To(const char* str) {
std::string tstr(str);
return tstr;
}
template<> std::wstring To(const char* str) {
//int iStrSize = (int)strlen(str);
int iSize = MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
//int iSize = (int)strlen(str);
std::wstring wstr(iSize-1, 0);
::MultiByteToWideChar(CP_ACP, 0, str, -1, &wstr[0], iSize);
return wstr;
}
template <> std::wstring To(const stringIteratorPair& StrPair) {
//int iStrSize =(int)(StrPair.second - StrPair.first);
int iSize = MultiByteToWideChar(CP_ACP,0,&(*StrPair.first),-1,NULL,0);
//int iSize = (int)(StrPair.second - StrPair.first);
std::wstring wstr(iSize-1, 0);
::MultiByteToWideChar(CP_ACP, 0, &(*StrPair.first), -1, &wstr[0], iSize);
return wstr;
}
template <> std::string To(int value) {
char szBuffer[12]; //mamximum 10 + 1 sign + 1 null.
_itoa(value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(int value) {
wchar_t wszBuffer[12];
_itow(value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(short value) {
char szBuffer[12];
_itoa((int)value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(short value) {
wchar_t wszBuffer[12];
_itow((int)value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(unsigned short value) {
char szBuffer[12];
_itoa((int)value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(unsigned short value) {
wchar_t wszBuffer[12];
_itow((int)value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(unsigned int value) {
char szBuffer[24];
_ui64toa((unsigned long)value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(unsigned int value) {
wchar_t wszBuffer[24];
_ui64tow((unsigned long)value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(__int64 value) {
char szBuffer[24];
_i64toa((unsigned long)value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(__int64 value) {
wchar_t wszBuffer[24];
_ui64tow((unsigned long)value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(unsigned __int64 value) {
char szBuffer[24];
_ui64toa((unsigned long)value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(unsigned __int64 value) {
wchar_t wszBuffer[24];
_ui64tow((unsigned long)value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(long value) {
char szBuffer[48];
_i64toa(value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(long value) {
wchar_t wszBuffer[48];
_i64tow(value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(unsigned long value) {
char szBuffer[100];
_ui64toa(value, szBuffer, 10);
return std::string(szBuffer);
}
template <> std::wstring To(unsigned long value) {
wchar_t wszBuffer[100];
_ui64tow(value, wszBuffer, 10);
return std::wstring(wszBuffer);
}
template <> std::string To(float value) {
char szBuffer[100];
sprintf(szBuffer, "%f", value);
return std::string(szBuffer);
}
template <> std::wstring To(float value) {
wchar_t wszBuffer[100];
swprintf(wszBuffer, L"%f", value);
return std::wstring(wszBuffer);
}
template <> std::string To(double value) {
char szBuffer[100];
sprintf(szBuffer, "%f", value);
return std::string(szBuffer);
}
template <> std::wstring To(double value) {
wchar_t wszBuffer[100];
swprintf(wszBuffer, L"%f", value);
return std::wstring(wszBuffer);
}
template <> std::string To(float2 value) {
char szBuffer[100*3];
sprintf(szBuffer, "(%f, %f)", value.x, value.y);
return std::string(szBuffer);
}
template <> std::wstring To(float2 value) {
wchar_t wszBuffer[100*3];
swprintf(wszBuffer, L"(%f, %f)", value.x, value.y);
return std::wstring(wszBuffer);
}
template <> std::string To(float3 value) {
char szBuffer[100*4];
sprintf(szBuffer, "(%f, %f, %f)", value.x, value.y, value.z);
return std::string(szBuffer);
}
template <> std::wstring To(float3 value) {
wchar_t wszBuffer[100*4];
swprintf(wszBuffer, L"(%f, %f, %f)", value.x, value.y, value.z);
return std::wstring(wszBuffer);
}
template <> std::string To(float4 value) {
char szBuffer[100*4];
sprintf(szBuffer, "(%f, %f, %f, %f)", value.x, value.y, value.z, value.w);
return std::string(szBuffer);
}
template <> std::wstring To(float4 value) {
wchar_t wszBuffer[100*4];
swprintf(wszBuffer, L"(%f, %f, %f, %f)", value.x, value.y, value.z, value.w);
return std::wstring(wszBuffer);
}
template <> double To(const char* str) { return atof(str); }
template <> double To(const stringIteratorPair& StrPair) { return To<double>(std::string(StrPair.first, StrPair.second)); }
template <> float To(const char* str) { return (float)To<double>(str); }
template <> float To(const stringIteratorPair& StrPair) { return (float)To<double>(StrPair); }
template <> int To(const char* str) { return atoi(str); }
template <> int To(const stringIteratorPair& StrPair) { return To<int>(std::string(StrPair.first, StrPair.second)); }
template <> double To(const wchar_t* wstr) { return _wtof(wstr); }
template <> double To(const wstringIteratorPair& StrPair) { return To<double>(std::wstring(StrPair.first, StrPair.second)); }
template <> float To(const wchar_t* wstr) { return (float)To<double>(wstr); }
template <> float To(const wstringIteratorPair& StrPair) { return (float)To<double>(StrPair); }
template <> int To(const wchar_t* str) { return _wtoi(str); }
template <> int To(const wstringIteratorPair& StrPair) { return To<int>(std::wstring(StrPair.first, StrPair.second)); }
/*
template <> short To(const wchar_t* str) { return (short)_wtoi(str); }
template <> short To(const wstringIteratorPair& StrPair) { return To<short>(std::wstring(StrPair.first, StrPair.second)); }
template <> long To(const wchar_t* str) { return _wtol(str); }
template <> long To(const wstringIteratorPair& StrPair) { return To<long>(std::wstring(StrPair.first, StrPair.second)); }
template <> unsigned int To(const wchar_t* str) { return (unsigned int)_wtoi(str); }
template <> unsigned int To(const wstringIteratorPair& StrPair) { return To<unsigned int>(std::wstring(StrPair.first, StrPair.second)); }
template <> unsigned short To(const wchar_t* str) { return (unsigned short)_wtoi(str); }
template <> unsigned short To(const wstringIteratorPair& StrPair) { return To<unsigned short>(std::wstring(StrPair.first, StrPair.second)); }
template <> unsigned long To(const wchar_t* str) { return (unsigned long)_wtol(str); }
template <> unsigned long To(const wstringIteratorPair& StrPair) { return To<unsigned long>(std::wstring(StrPair.first, StrPair.second)); }
*/
namespace Private {
template<typename T>
class Tokens {};
template<>
class Tokens<char> {
public:
static const char Minus = '-';
static const char LeftParenthesis = '(';
static const char RightParenthesis = ')';
static const char Comma = ',';
static const char Point = '.';
static const char Null = '\0';
static const char Zero = '0';
static const char Nine = '9';
static const char Space = ' ';
static const char Tab = '\t';
static const char LineFeed = '\n';
static const char CarriageReturn = '\r';
};
template<>
class Tokens<wchar_t> {
public:
static const wchar_t Minus = L'-';
static const wchar_t LeftParenthesis = L'(';
static const wchar_t RightParenthesis = L')';
static const wchar_t Comma = L',';
static const wchar_t Point = L'.';
static const wchar_t Null = L'\0';
static const wchar_t Zero = L'0';
static const wchar_t Nine = L'9';
static const wchar_t Space = L' ';
static const wchar_t Tab = L'\t';
static const wchar_t LineFeed = L'\n';
static const wchar_t CarriageReturn = L'\r';
};
template<typename T>
BOOL GetToken(T** pStr, T tToken) {
if( **pStr == tToken ) { (*pStr)++; return TRUE; }
return FALSE;
}
template<typename T>
BOOL IsNumber(T tChar) {
return (Tokens<T>::Zero <= tChar && tChar <= Tokens<T>::Nine) ? TRUE : FALSE;
}
template<typename T>
BOOL IsWhiteSpace(T tChar) {
return (tChar == Tokens<T>::Space || tChar == Tokens<T>::Tab ||
tChar == Tokens<T>::LineFeed || tChar == Tokens<T>::CarriageReturn) ? TRUE : FALSE;
}
template<typename T>
void SkipWhitespace(T** pStr) {
while( IsWhiteSpace(**pStr) ) (*pStr)++;
}
template<typename T>
void SkipNumbers(T** pStr) {
while( IsNumber(**pStr) ) (*pStr)++;
}
template<typename T>
void SkipFloat(T** pStr) {
//sign
GetToken(pStr, Tokens<T>::Minus);
//number before point
SkipNumbers(pStr);
//point
GetToken(pStr, Tokens<T>::Point);
//number after point
SkipNumbers(pStr);
}
}
template <> float2 To(const char* str) {
using namespace Private;
float2 ret;
char* pRead = const_cast<char*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, '(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float2 To(const stringIteratorPair &StrPair) { return To<float2>(std::string(StrPair.first, StrPair.second).c_str()); }
template <> float3 To(const char* str) {
using namespace Private;
float3 ret;
char* pRead = const_cast<char*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, '(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//z
SkipWhitespace(&pRead);
ret.z = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float3 To(const stringIteratorPair &StrPair) { return To<float3>(std::string(StrPair.first, StrPair.second).c_str()); }
template <> float4 To(const char* str) {
using namespace Private;
float4 ret;
char* pRead = const_cast<char*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, '(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//z
SkipWhitespace(&pRead);
ret.z = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, ',') ) return ret;
//w
SkipWhitespace(&pRead);
ret.w = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float4 To(const stringIteratorPair &StrPair) { return To<float4>(std::string(StrPair.first, StrPair.second).c_str()); }
template <> float2 To(const wchar_t* str) {
using namespace Private;
float2 ret;
wchar_t* pRead = const_cast<wchar_t*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L'(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float2 To(const wstringIteratorPair &StrPair) { return To<float2>(std::wstring(StrPair.first, StrPair.second).c_str()); }
template <> float3 To(const wchar_t* str) {
using namespace Private;
float3 ret;
wchar_t* pRead = const_cast<wchar_t*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L'(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//z
SkipWhitespace(&pRead);
ret.z = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float3 To(const wstringIteratorPair &StrPair) { return To<float3>(std::wstring(StrPair.first, StrPair.second).c_str()); }
template <> float4 To(const wchar_t* str) {
using namespace Private;
float4 ret;
wchar_t* pRead = const_cast<wchar_t*>(str);
//(
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L'(') ) return ret;
//x
SkipWhitespace(&pRead);
ret.x = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//y
SkipWhitespace(&pRead);
ret.y = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//z
SkipWhitespace(&pRead);
ret.z = To<float>(pRead);
SkipFloat(&pRead);
//,
SkipWhitespace(&pRead);
if( !GetToken(&pRead, L',') ) return ret;
//w
SkipWhitespace(&pRead);
ret.w = To<float>(pRead);
SkipFloat(&pRead);
//need not check )
return ret;
}
template<> float4 To(const wstringIteratorPair &StrPair) { return To<float4>(std::wstring(StrPair.first, StrPair.second).c_str()); }
}

View File

@@ -0,0 +1,97 @@
/**
* @file NFStringGenericConversion.h
* @brief 문자열 컨버팅 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include "NFTypes.h"
namespace Nave {
/**
Conversions work like
To<float>("123");
To<float>(L"123");
To<std::string>(L"hello world");
To<std::wstring>("hello world");
*/
unsigned int Hash(const WCHAR* str);
unsigned int Hash(const CHAR* str);
typedef std::pair<std::string::const_iterator,std::string::const_iterator> stringIteratorPair;
typedef std::pair<std::wstring::const_iterator,std::wstring::const_iterator> wstringIteratorPair;
template <typename T1, typename T2> T1 To(T2 value);
//generic conversion functions from string to actual type, also supports single(ascii)-wide(unicode conversions) character, if conversion to
//some type is not supported you will get a LINKING error
template <typename T> T To(const char* str);
template <typename T> inline T To(char* str) { return To<T>((const char*)str); }
template <typename T> inline T To(const std::string& str) { return To<T>(str.c_str()); }
template <typename T> T To(const stringIteratorPair& StrPair);
template <typename T> T To(const wchar_t* wstr);
template <typename T> inline T To(wchar_t* wstr) { return To<T>((const wchar_t*)wstr); }
template <typename T> inline T To(const std::wstring& wstr) { return To<T>(wstr.c_str()); }
template <typename T> T To(const wstringIteratorPair& StrPair);
//methods for converting between upper and lower case, supports both single and wide byte conversions
template <typename fc> inline void ToUpperCase(fc& s) { std::transform(s.begin(),s.end(),s.begin(),toupper); }
template <typename fc> inline void ToLowerCase(fc& s) { std::transform(s.begin(),s.end(),s.begin(),tolower); }
template <typename T> inline float ToFloat(const T& p) { return To<float>(p); }
template <typename T> inline float ToFloat(const T* p) { return To<float>(p); }
template <typename T> inline double ToDouble(const T& p) { return To<double>(p); }
template <typename T> inline double ToDouble(const T* p) { return To<double>(p); }
template <typename T> inline int ToInt(const T& p) { return To<int>(p); }
template <typename T> inline int ToInt(const T* p) { return To<int>(p); }
template <typename T> inline float2 ToFloat2(const T& p) { return To<float2>(p); }
template <typename T> inline float2 ToFloat2(const T* p) { return To<float2>(p); }
template <typename T> inline float3 ToFloat3(const T& p) { return To<float3>(p); }
template <typename T> inline float3 ToFloat3(const T* p) { return To<float3>(p); }
template <typename T> inline float4 ToFloat4(const T& p) { return To<float4>(p); }
template <typename T> inline float4 ToFloat4(const T* p) { return To<float4>(p); }
//@deprecated: convenience methods for single - wide byte conversions
inline Nave::String ToString(const std::string p)
{
return To<std::wstring>(p);
}
inline Nave::String ToString(const std::wstring p)
{
return p;
}
template <typename T> inline Nave::String ToNumber(const T& p)
{
Nave::String pstr = To<Nave::String>(p);
return ToString(pstr);
}
template <typename T> inline Nave::String ToNumber(const T* p)
{
Nave::String pstr = To<Nave::String>(p);
return ToString(pstr);
}
template <typename T> inline std::string ToASCII(const T& p) { return To<std::string>(p); }
template <typename T> inline std::string ToASCII(const T* p) { return To<std::string>(p); }
template <typename T> inline std::wstring ToUnicode(const T& p) { return To<std::wstring>(p); }
template <typename T> inline std::wstring ToUnicode(const T* p) { return To<std::wstring>(p); }
}

View File

@@ -0,0 +1,24 @@
/**
* @file NFStringUtil.h
* @brief 문자열 유틸리티 선언
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <windows.h>
#include <mmsystem.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <tchar.h>
#include <stddef.h> // 템플릿 라이브러리 헤더?
#include <conio.h>
#include "NFStringGenericConversion.h"
#include "NFStringGeneral.h"
#include "NFStringCompare.h"

View File

@@ -0,0 +1,80 @@
/**
* @file NFSync.h
* @brief Sync 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
namespace Nave {
/**
* @class NFSync
* @brief Sync 클래스
* @remarks
* NFSync Sync; \r\n
* NFSyncLock CL(&Sync);
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFSync
{
public:
NFSync(VOID)
{
InitializeCriticalSection(&m_Sync);
}
~NFSync(VOID)
{
DeleteCriticalSection(&m_Sync);
}
inline VOID Enter(VOID)
{
EnterCriticalSection(&m_Sync);
}
inline VOID Leave(VOID)
{
LeaveCriticalSection(&m_Sync);
}
private:
CRITICAL_SECTION m_Sync;
};
/**
* @class NFSyncLock
* @brief 싱글스레드용 싱크
* @remarks
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFSyncLock
{
public:
NFSyncLock(LPVOID lpVoid)
{
m_pThis = (NFSync*)lpVoid;
m_pThis->Enter();
}
~NFSyncLock(VOID)
{
if(m_pThis)
m_pThis->Leave();
}
private:
NFSync *m_pThis;
};
}

View File

@@ -0,0 +1,61 @@
/**
* @file NFThread.h
* @brief Auto Thread 생성 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <windows.h>
namespace Nave {
/**
* @class NFThread
* @brief 스레드 객체 클래스
* @remarks
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFThread
{
public:
NFThread() : m_hThreadHandle(INVALID_HANDLE_VALUE)
{
}
~NFThread()
{
}
typedef unsigned int(__stdcall *LPThreadFunc)(void*);
/// 스레드 함수포인터
static inline unsigned int __stdcall ThreadFunc(void* pArg);
/// 스레드 핸들을 리턴한다.
inline HANDLE GetHandle() { return m_hThreadHandle; }
/// 스레드 핸들을 설정한다.
inline void SetHandle(HANDLE hHandle) { m_hThreadHandle = hHandle; }
/// 실제 실행 되는 루프를 넣는다.
virtual unsigned int Run() = 0;
/// 루프가 끝날 수 있는 루틴을 넣는다.
virtual BOOL End() = 0;
private:
/// 스레드핸들
HANDLE m_hThreadHandle;
// friend class NFThreadManager;
};
/// 스레드 호출함수
inline unsigned int __stdcall NFThread::ThreadFunc(void* pArg)
{
return static_cast<NFThread*>(pArg)->Run();
}
}

View File

@@ -0,0 +1,129 @@
#include "Nave.h"
#include "NFThread.h"
#include "NFThreadManager.h"
namespace Nave {
HANDLE NFThreadManager::Run(NFThread* lpThread)
{
unsigned int nThreadID = 0;
HANDLE hThread = reinterpret_cast<HANDLE>(_beginthreadex(0,
0, NFThread::ThreadFunc, lpThread, 0, &nThreadID));
lpThread->SetHandle(hThread);
return hThread;
}
BOOL NFThreadManager::Stop(NFThread* lpThread, unsigned long dwTimeout)
{
if(0 == lpThread)
{
return FALSE;
}
HANDLE hThread = lpThread->GetHandle();
if(INVALID_HANDLE_VALUE == hThread)
{
return FALSE;
}
lpThread->SetHandle(INVALID_HANDLE_VALUE);
lpThread->End();
WaitForSingleObject(hThread, dwTimeout);
return (TRUE == CloseHandle(hThread));
}
NFThreadManager::NFThreadManager() : m_nThreadNum(0), m_bUnRegStarted(FALSE)
{
for(int i = 0; i < MAX_THREAD_NUM; ++i)
{
m_lpThreads[i] = NULL;
m_hThreads[i] = NULL;
}
}
NFThreadManager::~NFThreadManager()
{
UnRegister();
}
BOOL NFThreadManager::Register(NFThread* llpThread)
{
unsigned int nThreadID = 0;
unsigned int nThreadIndex = 0;
if(0 == llpThread)
{
return FALSE;
}
// Lock
{
Nave::NFSyncLock Sync(&m_ThreadLock);
if(MAX_THREAD_NUM <= m_nThreadNum || TRUE == m_bUnRegStarted)
{
return FALSE;
}
nThreadIndex = m_nThreadNum;
++m_nThreadNum;
}
m_lpThreads[nThreadIndex] = llpThread;
m_hThreads[nThreadIndex] = reinterpret_cast<HANDLE>(_beginthreadex(0, 0,
NFThread::ThreadFunc, llpThread, 0, &nThreadID));
return (0 != m_hThreads[nThreadIndex]);
}
BOOL NFThreadManager::UnRegister()
{
{
Nave::NFSyncLock Sync(&m_ThreadLock);
if(0 == m_nThreadNum)
{
return TRUE;
}
// 조인이 시작되면, 더이상의 스레드 생성 및 등록을 금지함.
m_bUnRegStarted = TRUE;
}
// 스레드 전부 종료 & 대기.
for(int i = 0; i < (int)m_nThreadNum; ++i)
{
if(m_lpThreads[i])
{
m_lpThreads[i]->End();
}
}
WaitForMultipleObjects(m_nThreadNum, m_hThreads, TRUE, INFINITE);
// 스레드 소멸.
for(int i = 0; i < MAX_THREAD_NUM; ++i)
{
_DELETE(m_lpThreads[i]);
if(m_hThreads[i])
{
CloseHandle(m_hThreads[i]);
m_hThreads[i] = NULL;
}
}
{
// 스레드 개수 및 조인 여부 리셋.
Nave::NFSyncLock Sync(&m_ThreadLock);
m_nThreadNum = 0;
m_bUnRegStarted = FALSE;
}
return TRUE;
}
}

View File

@@ -0,0 +1,75 @@
/**
* @file NFThreadManager.h
* @brief Auto ThreadManager 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include "NFSync.h"
#include "NFThread.h"
namespace Nave {
/**
* @class NFThreadManager
* @brief 스레드 매니져
* @remarks
* 1) NFThread 를 상속받은 녀석 \r\n
* \r\n
* Nave::NFThreadManager::Run(this); \r\n
* Nave::NFThreadManager::Stop(this, 2000); \r\n
* \r\n
* 2) 스레드 매니져를 사용하려면 \r\n
* Nave::NFThreadManager::GetInstance().Register( new CTest(this) ); \r\n
* \r\n
* // 소멸시 자동으로 UnRegister가 호출되어메모리에서 삭제됨.. \r\n
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFThreadManager : public Nave::NFSingleton<NFThreadManager>
{
public:
/// NFThreadManager 생성자
NFThreadManager();
/// NFThreadManager 소멸자
virtual ~NFThreadManager();
/// 스레드를 등록한다. 최대 32개까지 등록할 수 있다.
BOOL Register(NFThread* lpThread);
/// 모든 스레드를 종료시킨다.
BOOL UnRegister();
/// 매니저를 사용하지 않고, 그냥 실행 시킨다.
static HANDLE Run(NFThread* lpThread);
/// 매니저를 사용하지 않고, 그냥 종료 시킨다.
static BOOL Stop(NFThread* lpThread, unsigned long dwTimeout = INFINITE);
private:
enum {
MAX_THREAD_NUM = 32 /// 최대 스레드 개수
};
/// 스레드 객체 포인터
NFThread* m_lpThreads[MAX_THREAD_NUM];
/// 스레드 핸들
HANDLE m_hThreads[MAX_THREAD_NUM];
/// 스레드 Lock
Nave::NFSync m_ThreadLock;
/// 스레드 개수
Nave::uint32 m_nThreadNum;
/// UnRegister의 진행여부
Nave::uint32 m_bUnRegStarted;
};
}

View File

@@ -0,0 +1,322 @@
#include "Nave.h"
#include "NFTokenizer.h"
namespace Nave {
NFTokenizerA::NFTokenizerA(const std::string& _str, const std::string& _delim)
{
if ((_str.length() == 0) || (_delim.length() == 0)) return;
token_str = _str;
delim = _delim;
/*
Remove sequential delimiter
*/
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::string::npos)
{
curr_pos += delim.length();
while(token_str.find(delim,curr_pos) == curr_pos)
{
token_str.erase(curr_pos,delim.length());
}
}
else
break;
}
/*
Trim leading delimiter
*/
if (token_str.find(delim,0) == 0)
{
token_str.erase(0,delim.length());
}
/*
Trim ending delimiter
*/
curr_pos = 0;
if ((curr_pos = token_str.rfind(delim)) != std::string::npos)
{
if (curr_pos != (token_str.length() - delim.length())) return;
token_str.erase(token_str.length() - delim.length(),delim.length());
}
}
int NFTokenizerA::CountTokens()
{
unsigned int prev_pos = 0;
int num_tokens = 0;
if (token_str.length() > 0)
{
num_tokens = 0;
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::string::npos)
{
num_tokens++;
prev_pos = curr_pos;
curr_pos += delim.length();
}
else
break;
}
return ++num_tokens;
}
else
{
return 0;
}
}
bool NFTokenizerA::HasMoreTokens()
{
return (token_str.length() > 0);
}
std::string NFTokenizerA::NextToken()
{
if (token_str.length() == 0)
return "";
std::string tmp_str = "";
unsigned int pos = token_str.find(delim,0);
if (pos != std::string::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos+delim.length(),token_str.length()-pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = "";
}
return tmp_str;
}
int NFTokenizerA::NextIntToken()
{
return atoi(NextToken().c_str());
}
double NFTokenizerA::NextFloatToken()
{
return atof(NextToken().c_str());
}
std::string NFTokenizerA::NextToken(const std::string& delimiter)
{
if (token_str.length() == 0)
return "";
std::string tmp_str = "";
unsigned int pos = token_str.find(delimiter,0);
if (pos != std::string::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos + delimiter.length(),token_str.length() - pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = "";
}
return tmp_str;
}
std::string& NFTokenizerA::RemainingString()
{
return token_str;
}
std::string NFTokenizerA::FilterNextToken(const std::string& filterStr)
{
std::string tmp_str = NextToken();
unsigned int currentPos = 0;
while((currentPos = tmp_str.find(filterStr,currentPos)) != std::string::npos)
{
tmp_str.erase(currentPos,filterStr.length());
}
return tmp_str;
}
// unicode type
NFTokenizerW::NFTokenizerW(const std::wstring& _str, const std::wstring& _delim)
{
if ((_str.length() == 0) || (_delim.length() == 0)) return;
token_str = _str;
delim = _delim;
/*
Remove sequential delimiter
*/
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::wstring::npos)
{
curr_pos += delim.length();
while(token_str.find(delim,curr_pos) == curr_pos)
{
token_str.erase(curr_pos,delim.length());
}
}
else
break;
}
/*
Trim leading delimiter
*/
if (token_str.find(delim,0) == 0)
{
token_str.erase(0,delim.length());
}
/*
Trim ending delimiter
*/
curr_pos = 0;
if ((curr_pos = token_str.rfind(delim)) != std::wstring::npos)
{
if (curr_pos != (token_str.length() - delim.length())) return;
token_str.erase(token_str.length() - delim.length(),delim.length());
}
}
int NFTokenizerW::CountTokens()
{
unsigned int prev_pos = 0;
int num_tokens = 0;
if (token_str.length() > 0)
{
num_tokens = 0;
unsigned int curr_pos = 0;
while(true)
{
if ((curr_pos = token_str.find(delim,curr_pos)) != std::wstring::npos)
{
num_tokens++;
prev_pos = curr_pos;
curr_pos += delim.length();
}
else
break;
}
return ++num_tokens;
}
else
{
return 0;
}
}
bool NFTokenizerW::HasMoreTokens()
{
return (token_str.length() > 0);
}
std::wstring NFTokenizerW::NextToken()
{
if (token_str.length() == 0)
return L"";
std::wstring tmp_str = L"";
unsigned int pos = token_str.find(delim,0);
if (pos != std::wstring::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos+delim.length(),token_str.length()-pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = L"";
}
return tmp_str;
}
int NFTokenizerW::NextIntToken()
{
return _wtoi(NextToken().c_str());
}
double NFTokenizerW::NextFloatToken()
{
return _wtof(NextToken().c_str());
}
std::wstring NFTokenizerW::NextToken(const std::wstring& delimiter)
{
if (token_str.length() == 0)
return L"";
std::wstring tmp_str = L"";
unsigned int pos = token_str.find(delimiter,0);
if (pos != std::wstring::npos)
{
tmp_str = token_str.substr(0,pos);
token_str = token_str.substr(pos + delimiter.length(),token_str.length() - pos);
}
else
{
tmp_str = token_str.substr(0,token_str.length());
token_str = L"";
}
return tmp_str;
}
std::wstring& NFTokenizerW::RemainingString()
{
return token_str;
}
std::wstring NFTokenizerW::FilterNextToken(const std::wstring& filterStr)
{
std::wstring tmp_str = NextToken();
unsigned int currentPos = 0;
while((currentPos = tmp_str.find(filterStr,currentPos)) != std::wstring::npos)
{
tmp_str.erase(currentPos,filterStr.length());
}
return tmp_str;
}
}

View File

@@ -0,0 +1,120 @@
/**
* @file NFTokenizer.h
* @brief Tokenizer 클래스
* @remarks
* @author 강동명(edith2580@gmail.com)
* @date 2009-04-02
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
namespace Nave {
/**
* @class NFTokenizerA
* @brief 멀티바이트용 Tokenizer
* @remarks
* Nave::String tempStr = L"01|02|03|04|05|06|07|08|09|10|11|12"; \r\n
* \r\n
* Nave::NFTokenizer strtok = Nave::NFTokenizer(tempStr, L"|"); \r\n
* \r\n
* LOG_IMPORTANT((L"Number Of Tokens: %d"), strtok.CountTokens()); \r\n
* LOG_IMPORTANT((L"String: %s"), strtok.RemainingString().c_str()); \r\n
* \r\n
* int cnt = strtok.CountTokens(); \r\n
* Nave::String finalString = L""; \r\n
* \r\n
* for(int i = 0; i < cnt; i++) \r\n
* { \r\n
* Nave::String tempStr = L""; \r\n
* \r\n
* LOG_IMPORTANT((L"Token[%d] ----> [%s]"), i, strtok.NextToken().c_str());\r\n
* LOG_IMPORTANT((L"Token Count : %d"), strtok.CountTokens()); \r\n
* \r\n
* finalString += tempStr; \r\n
* } \r\n
* \r\n
* LOG_IMPORTANT((L"Final String : %s"), finalString.c_str());
*
* @par
* @author Edith
* @date 2009-04-05
*/
class NFTokenizerA
{
public:
NFTokenizerA(const std::string& _str, const std::string& _delim);
~NFTokenizerA(){};
int CountTokens();
bool HasMoreTokens();
std::string NextToken();
int NextIntToken();
double NextFloatToken();
std::string NextToken(const std::string& delim);
std::string& RemainingString();
std::string FilterNextToken(const std::string& filterStr);
private:
std::string token_str;
std::string delim;
};
/**
* @class NFTokenizerW
* @brief 유니코드용 Tokenizer
* @remarks
* Nave::String tempStr = L"01|02|03|04|05|06|07|08|09|10|11|12"; \r\n
* \r\n
* Nave::NFTokenizer strtok = Nave::NFTokenizer(tempStr, L"|"); \r\n
* \r\n
* LOG_IMPORTANT((L"Number Of Tokens: %d"), strtok.CountTokens()); \r\n
* LOG_IMPORTANT((L"String: %s"), strtok.RemainingString().c_str()); \r\n
* \r\n
* int cnt = strtok.CountTokens(); \r\n
* Nave::String finalString = L""; \r\n
* \r\n
* for(int i = 0; i < cnt; i++) \r\n
* { \r\n
* Nave::String tempStr = L""; \r\n
* \r\n
* LOG_IMPORTANT((L"Token[%d] ----> [%s]"), i, strtok.NextToken().c_str());\r\n
* LOG_IMPORTANT((L"Token Count : %d"), strtok.CountTokens()); \r\n
* \r\n
* finalString += tempStr; \r\n
* } \r\n
* \r\n
* LOG_IMPORTANT((L"Final String : %s"), finalString.c_str());
* @par
* @author Edith
* @date 2009-04-05
*/
class NFTokenizerW
{
public:
NFTokenizerW(const std::wstring& _str, const std::wstring& _delim);
~NFTokenizerW(){};
int CountTokens();
bool HasMoreTokens();
std::wstring NextToken();
int NextIntToken();
double NextFloatToken();
std::wstring NextToken(const std::wstring& delim);
std::wstring& RemainingString();
std::wstring FilterNextToken(const std::wstring& filterStr);
private:
std::wstring token_str;
std::wstring delim;
};
typedef NFTokenizerW NFTokenizer;
}

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