@@ -25,6 +25,16 @@ | |||||
*.la | *.la | ||||
*.a | *.a | ||||
*.lib | *.lib | ||||
*.pdb | |||||
*.ilk | |||||
*.exp | |||||
*.tlog | |||||
*.tli | |||||
*.tlh | |||||
*.log | |||||
*.sbr | |||||
*.idb | |||||
*.txt | |||||
# Executables | # Executables | ||||
*.exe | *.exe | ||||
@@ -34,3 +44,7 @@ | |||||
!MSADO15.DLL | !MSADO15.DLL | ||||
!libcurl.lib | !libcurl.lib | ||||
!zip.lib | !zip.lib | ||||
!create_dumpD.lib | |||||
!create_dump.lib | |||||
.vs |
@@ -14,42 +14,18 @@ | |||||
#include <google/protobuf/wire_format.h> | #include <google/protobuf/wire_format.h> | ||||
// @@protoc_insertion_point(includes) | // @@protoc_insertion_point(includes) | ||||
#include <google/protobuf/port_def.inc> | #include <google/protobuf/port_def.inc> | ||||
<<<<<<< .mine | |||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto; | ||||
extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto; | extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto; | ||||
||||||| .r248 | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
======= | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
>>>>>>> .r273 | |||||
namespace Club { | namespace Club { | ||||
class PB_CS_C_ClubListDefaultTypeInternal { | class PB_CS_C_ClubListDefaultTypeInternal { | ||||
public: | public: | ||||
@@ -814,17 +790,9 @@ static void InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2e | |||||
::Club::PB_CS_S_tagClubIntegral::InitAsDefaultInstance(); | ::Club::PB_CS_S_tagClubIntegral::InitAsDefaultInstance(); | ||||
} | } | ||||
<<<<<<< .mine | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto}, {}}; | |||||
||||||| .r248 | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; | |||||
======= | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, { | |||||
&scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base,}}; | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto}, { | |||||
&scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base,}}; | |||||
static void InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto() { | static void InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto() { | ||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
@@ -837,24 +805,11 @@ static void InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2 | |||||
::Club::PB_CS_S_tagClubPlaygames::InitAsDefaultInstance(); | ::Club::PB_CS_S_tagClubPlaygames::InitAsDefaultInstance(); | ||||
} | } | ||||
<<<<<<< .mine | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto}, {}}; | |||||
||||||| .r248 | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; | |||||
======= | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, { | |||||
&scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base,}}; | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto}, { | |||||
&scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base,}}; | |||||
<<<<<<< .mine | |||||
static void InitDefaultsscc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto() { | |||||
||||||| .r248 | |||||
static void InitDefaultsscc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { | |||||
======= | |||||
static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { | |||||
static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto() { | |||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
{ | { | ||||
@@ -865,10 +820,10 @@ static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_ | |||||
::Club::PB_CS_tagClubIntegral::InitAsDefaultInstance(); | ::Club::PB_CS_tagClubIntegral::InitAsDefaultInstance(); | ||||
} | } | ||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto}, {}}; | |||||
static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { | |||||
static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto() { | |||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
{ | { | ||||
@@ -879,11 +834,10 @@ static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb | |||||
::Club::PB_CS_tagClubPlaygames::InitAsDefaultInstance(); | ::Club::PB_CS_tagClubPlaygames::InitAsDefaultInstance(); | ||||
} | } | ||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto}, {}}; | |||||
static void InitDefaultsscc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { | |||||
>>>>>>> .r273 | |||||
static void InitDefaultsscc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto() { | |||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
{ | { | ||||
@@ -953,19 +907,9 @@ static void InitDefaultsscc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto( | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto = | ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto = | ||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto}, {}}; | {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto}, {}}; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fClubInformation_2eproto[46]; | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fClubInformation_2eproto[48]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fClubInformation_2eproto = nullptr; | static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fClubInformation_2eproto = nullptr; | ||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fClubInformation_2eproto = nullptr; | static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fClubInformation_2eproto = nullptr; | ||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[46]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[48]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; | |||||
>>>>>>> .r273 | |||||
const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fClubInformation_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { | const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fClubInformation_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { | ||||
~0u, // no _has_bits_ | ~0u, // no _has_bits_ | ||||
@@ -1524,7 +1468,6 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = | |||||
reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::Club::_PB_CS_Club_Make_A_Sample_default_instance_), | reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::Club::_PB_CS_Club_Make_A_Sample_default_instance_), | ||||
}; | }; | ||||
<<<<<<< .mine | |||||
const char descriptor_table_protodef_Pb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | const char descriptor_table_protodef_Pb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | ||||
"\n\030Pb_ClubInformation.proto\022\004Club\"7\n\020PB_C" | "\n\030Pb_ClubInformation.proto\022\004Club\"7\n\020PB_C" | ||||
"S_C_ClubList\022\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCo" | "S_C_ClubList\022\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCo" | ||||
@@ -1648,300 +1591,25 @@ const char descriptor_table_protodef_Pb_5fClubInformation_2eproto[] PROTOBUF_SEC | |||||
"teTableID\030\002 \001(\r\"p\n\025PB_CS_C_ClubPlaygames" | "teTableID\030\002 \001(\r\"p\n\025PB_CS_C_ClubPlaygames" | ||||
"\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\nSta" | "\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\nSta" | ||||
"rtIndex\030\003 \001(\r\022\016\n\006mCount\030\004 \001(\r\022\022\n\nwDateCo" | "rtIndex\030\003 \001(\r\022\016\n\006mCount\030\004 \001(\r\022\022\n\nwDateCo" | ||||
"unt\030\005 \001(\r\"\205\001\n\030PB_CS_S_tagClubPlaygames\022\020" | |||||
"\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\022\n\nszUs" | |||||
"erName\030\003 \001(\t\022\021\n\tszHeadImg\030\004 \001(\t\022\022\n\nwDate" | |||||
"Count\030\005 \001(\r\022\014\n\004temp\030\006 \001(\r\"K\n\024PB_CS_C_Clu" | |||||
"bIntegral\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001" | |||||
"(\r\022\022\n\nwDateCount\030\003 \001(\r\"\224\001\n\027PB_CS_S_tagCl" | |||||
"ubIntegral\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002" | |||||
" \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022\n\nszUserName\030\004 \001(\t" | |||||
"\022\021\n\tszHeadImg\030\005 \001(\t\022\022\n\nwDateCount\030\006 \001(\r\022" | |||||
"\014\n\004temp\030\007 \001(\r\">\n\030PB_CS_Club_Make_A_Sampl" | |||||
"e\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010IsSample\030\002 \001(\rb\006p" | |||||
"roto3" | |||||
||||||| .r248 | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n*Source/MessageDef/Pb_ClubInformation.p" | |||||
"roto\022\004Club\"7\n\020PB_CS_C_ClubList\022\023\n\013wStart" | |||||
"Index\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"\272\002\n\021pb_tagTa" | |||||
"bleConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\021\n\twPlayRu" | |||||
"le\030\002 \001(\r\022\023\n\013wMaxFanRule\030\003 \001(\r\022\021\n\twMaxSco" | |||||
"re\030\004 \001(\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\025\n\rwHad" | |||||
"PlayCount\030\006 \001(\r\022\023\n\013zmExtraRule\030\007 \001(\r\022\017\n\007" | |||||
"dghRule\030\010 \001(\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017" | |||||
"\n\007bDuoLai\030\n \001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tm" | |||||
"p1\030\014 \001(\r\022\014\n\004tmp2\030\r \001(\r\022\014\n\004tmp3\030\016 \001(\r\022\014\n\004" | |||||
"tmp4\030\017 \001(\r\022\014\n\004tmp5\030\020 \001(\r\"n\n\024PB_CS_S_Club" | |||||
"List_Ack\022\022\n\nwNewsCount\030\001 \001(\r\022\022\n\nwClubCou" | |||||
"nt\030\002 \001(\r\022.\n\016csGameClubInfo\030\003 \003(\0132\026.Club." | |||||
"PB_CS_C_ClubInfo\":\n\023PB_CS_C_ClubMessage\022" | |||||
"\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"H\n\016" | |||||
"pb_MessageInfo\022\r\n\005dType\030\001 \001(\r\022\021\n\tszConte" | |||||
"nt\030\002 \001(\t\022\024\n\014dtActionTime\030\003 \001(\r\"T\n\027PB_CS_" | |||||
"S_ClubMessage_Ack\022\016\n\006wCount\030\001 \001(\r\022)\n\013Mes" | |||||
"sageInfo\030\002 \003(\0132\024.Club.pb_MessageInfo\"x\n\022" | |||||
"PB_CS_C_ClubRecord\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013" | |||||
"wStartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\023\n\013dtS" | |||||
"tartTime\030\004 \001(\r\022\026\n\016dwPrivatetable\030\005 \001(\r\"$" | |||||
"\n\rpb_PlayerName\022\023\n\013PlayerName2\030\001 \001(\t\"\264\001\n" | |||||
"\022PB_CS_S_RecordInfo\022\021\n\tdwTableID\030\001 \001(\r\022\017" | |||||
"\n\007cbJuShu\030\002 \001(\r\022\020\n\010cbPayWay\030\003 \001(\r\022\026\n\016dwT" | |||||
"ableOwnerID\030\004 \001(\r\022\024\n\014dtCreateTime\030\005 \001(\r\022" | |||||
"\020\n\010PlayerID\030\006 \003(\r\022(\n\013PlayerName1\030\007 \003(\0132\023" | |||||
".Club.pb_PlayerName\"\\\n\024PB_CS_S_RecordInf" | |||||
"oEX\022(\n\006Record\030\001 \001(\0132\030.Club.PB_CS_S_Recor" | |||||
"dInfo\022\r\n\005Score\030\002 \003(\022\022\013\n\003Tmp\030\003 \003(\r\"\227\001\n\031PB" | |||||
"_CS_S_ClubRecord_Ack_EX\022\016\n\006wCount\030\001 \001(\r\022" | |||||
"\024\n\014dwTableCount\030\002 \001(\r\022\020\n\010dwZunShi\030\003 \001(\r\022" | |||||
"\020\n\010dwClubID\030\004 \001(\r\0220\n\014csRecordInfo\030\005 \003(\0132" | |||||
"\032.Club.PB_CS_S_RecordInfoEX\"\304\002\n\020PB_CS_C_" | |||||
"ClubInfo\022\020\n\010dwClubID\030\001 \001(\r\022\022\n\nszClubName" | |||||
"\030\002 \001(\t\022\021\n\tcbIsOwner\030\003 \001(\r\022\021\n\twTotalNum\030\004" | |||||
" \001(\r\022\025\n\rwWaitTableNum\030\005 \001(\r\022\022\n\nwOnLineNu" | |||||
"m\030\006 \001(\r\022\024\n\014wWaitUserNum\030\007 \001(\r\022\021\n\tdwOwner" | |||||
"ID\030\010 \001(\r\022\022\n\nszHostName\030\t \001(\t\022\021\n\tszHeadUr" | |||||
"l\030\n \001(\t\022\r\n\005temp1\030\013 \001(\r\022\r\n\005temp2\030\014 \001(\r\022\r\n" | |||||
"\005temp3\030\r \001(\r\022\r\n\005temp4\030\016 \001(\r\022-\n\014csGameCon" | |||||
"fig\030\017 \001(\0132\027.Club.pb_tagTableConfig\"(\n\024PB" | |||||
"_CS_C_Club_Action1\022\020\n\010dwClubID\030\001 \001(\r\";\n\030" | |||||
"PB_CS_S_Club_Action_Ack1\022\016\n\006Result\030\001 \001(\r" | |||||
"\022\017\n\007Message\030\002 \001(\t\"e\n\030PB_CS_S_Club_Action" | |||||
"_Ack2\022\016\n\006Result\030\001 \001(\r\022(\n\010ClubInfo\030\002 \001(\0132" | |||||
"\026.Club.PB_CS_C_ClubInfo\022\017\n\007Message\030\003 \001(\t" | |||||
"\"M\n\024PB_CS_C_Club_Action2\022\020\n\010dwClubID\030\001 \001" | |||||
"(\r\022\020\n\010dwUserID\030\002 \001(\r\022\021\n\tcbIsAgree\030\003 \001(\r\"" | |||||
"]\n\030PB_CS_S_Club_Action_Ack3\022\017\n\007wClubID\030\001" | |||||
" \001(\r\022\016\n\006Result\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\017\n" | |||||
"\007cbAgree\030\004 \001(\r\"]\n\024PB_CS_C_ClubOnLineEx\022\020" | |||||
"\n\010dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n" | |||||
"\006wCount\030\003 \001(\r\022\016\n\006cbType\030\004 \001(\r\"\247\001\n\030PB_CS_" | |||||
"S_ClubOnLine_AckEx\022\020\n\010dwClubID\030\001 \001(\r\022\024\n\014" | |||||
"wQueTableNum\030\002 \001(\r\022\025\n\rwWaitTableNum\030\003 \001(" | |||||
"\r\022\025\n\rwPlayTableNmu\030\004 \001(\r\022\014\n\004temp\030\005 \001(\r\022\026" | |||||
"\n\016wtotalTableNum\030\006 \001(\r\022\017\n\007tableID\030\007 \003(\r\"" | |||||
"s\n\031PB_CS_S_Club_Notify_ACKEX\022\020\n\010newsFalg" | |||||
"\030\001 \001(\r\022\014\n\004Temp\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\020\n" | |||||
"\010dwClubID\030\004 \001(\r\022\023\n\013dwUserCount\030\005 \001(\r\"j\n\021" | |||||
"PB_CS_C_ClubUser2\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013w" | |||||
"StartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\016\n\006cbKi" | |||||
"nd\030\004 \001(\r\022\016\n\006dwTemp\030\005 \001(\r\"\216\001\n\022PB_CS_S_Mem" | |||||
"berInfo\022\020\n\010BangMaID\030\001 \001(\r\022\017\n\007cbStaus\030\002 \001" | |||||
"(\r\022\016\n\006isHost\030\003 \001(\r\022\020\n\010isOnline\030\004 \001(\r\022\020\n\010" | |||||
"dwUserID\030\005 \001(\r\022\016\n\006szName\030\006 \001(\t\022\021\n\tszHead" | |||||
"Url\030\007 \001(\t\"\226\001\n\025PB_CS_S_ClubUser2_Ack\022\016\n\006c" | |||||
"bKind\030\001 \001(\r\022\013\n\003tmp\030\002 \001(\r\022\016\n\006cbHost\030\003 \001(\r" | |||||
"\022\020\n\010dwClubID\030\004 \001(\r\022\016\n\006wCount\030\005 \001(\r\022.\n\014cs" | |||||
"MemberInfo\030\006 \003(\0132\030.Club.PB_CS_S_MemberIn" | |||||
"fo\"8\n\024PB_CS_C_ClubProtocol\022\020\n\010dwClubID\030\001" | |||||
" \001(\r\022\016\n\006dwTemp\030\002 \001(\r\"N\n\031PB_CS_S_ClubProt" | |||||
"ocolAgree\022\020\n\010dwClubID\030\001 \001(\r\022\017\n\007cbAgree\030\002" | |||||
" \001(\r\022\016\n\006dwTemp\030\003 \001(\r\"K\n\026PB_CS_S_ClubActi" | |||||
"onAck1\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006Result\030\002 \001(\r" | |||||
"\022\017\n\007Message\030\003 \001(\t\"W\n\022PB_CS_C_ClubNotice\022" | |||||
"\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030\002 \001(\r\022\016\n\006dwT" | |||||
"emp\030\003 \001(\r\022\017\n\007Message\030\004 \001(\t\"l\n\025PB_CS_S_Cl" | |||||
"ubNoticeACK\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030" | |||||
"\002 \001(\r\022\016\n\006dwTemp\030\003 \001(\r\022\020\n\010cbResult\030\004 \001(\r\022" | |||||
"\017\n\007Message\030\005 \001(\t\"I\n\020PB_CS_C_ClubUser\022\020\n\010" | |||||
"dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n\006w" | |||||
"Count\030\003 \001(\r\"x\n\024PB_CS_S_ClubUser_Ack\022\016\n\006c" | |||||
"bHost\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\016\n\006wCount\030" | |||||
"\003 \001(\r\022.\n\014csMemberInfo\030\004 \003(\0132\030.Club.PB_CS" | |||||
"_S_MemberInfo\"N\n\027PB_CS_C_ClubOnLineTable" | |||||
"\022\016\n\006cbType\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\021\n\tdw" | |||||
"TableID\030\003 \001(\r\"\273\002\n\017pb_RoomListInfo\022\016\n\006szN" | |||||
"ame\030\001 \001(\t\022\022\n\ndwServerID\030\002 \001(\r\022\014\n\004szIp\030\003 " | |||||
"\001(\t\022\017\n\007bDuoLai\030\004 \001(\r\022\021\n\twFengDing\030\005 \001(\r\022" | |||||
"\014\n\004tmp1\030\006 \001(\r\022\014\n\004tmp2\030\007 \001(\r\022\014\n\004tmp6\030\010 \003(" | |||||
"\022\022\r\n\005wPort\030\t \001(\r\022\024\n\014dwRoomNumber\030\n \001(\r\022\017" | |||||
"\n\007dwDiFen\030\013 \001(\r\022\017\n\007dwJuShu\030\014 \001(\r\022\026\n\016bRoo" | |||||
"mCreatePay\030\r \001(\r\022\017\n\007bFanGua\030\016 \001(\r\022\016\n\006bWa" | |||||
"nFa\030\017 \001(\r\022\014\n\004tmp3\030\020 \001(\r\022\014\n\004tmp4\030\021 \001(\r\022\014\n" | |||||
"\004tmp5\030\022 \001(\r\"V\n\034PB_CS_S_ClubOnLineTableCf" | |||||
"Ack\022\021\n\tdwTableID\030\001 \001(\r\022#\n\004Room\030\002 \001(\0132\025.C" | |||||
"lub.pb_RoomListInfo\"D\n\rpb_PlayerInfo\022\020\n\010" | |||||
"dwUserID\030\001 \001(\r\022\016\n\006szName\030\002 \001(\t\022\021\n\tszHead" | |||||
"Url\030\003 \001(\t\"{\n\032PB_CS_S_ClubOnLineTableAck\022" | |||||
"\021\n\tdwTableID\030\001 \001(\r\022\016\n\006wJushu\030\002 \001(\r\022\023\n\013wT" | |||||
"ableState\030\003 \001(\r\022%\n\010Userinfo\030\004 \003(\0132\023.Club" | |||||
".pb_PlayerInfo\"E\n\024PB_CS_S_Table_Notify\022\014" | |||||
"\n\004type\030\001 \001(\r\022\017\n\007tableID\030\002 \001(\r\022\016\n\006clubID\030" | |||||
"\003 \001(\r\"\324\001\n\035PB_CS_S_TableOtherInfo_Notify\022" | |||||
"\016\n\006ClubID\030\001 \001(\r\022\014\n\004Type\030\002 \001(\r\022\024\n\014totalUs" | |||||
"erNum\030\003 \001(\004\022\025\n\ronlineUserNum\030\004 \001(\004\022\025\n\rto" | |||||
"talTableNum\030\005 \001(\004\022\021\n\tnewMsgNum\030\006 \001(\r\022\022\n\n" | |||||
"newUserNum\030\007 \001(\r\022\024\n\014waitTableNum\030\010 \001(\r\022\024" | |||||
"\n\014playTableNum\030\t \001(\r\">\n\030PB_CS_C_ClubDiss" | |||||
"olveRoom\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010dwRoomID\030\002" | |||||
" \001(\r\"}\n\027PB_CS_C_ClubAutoAddInfo\022\020\n\010dwClu" | |||||
"bID\030\001 \001(\r\022\021\n\tcbWanfaId\030\002 \001(\r\022\020\n\010cbStatus" | |||||
"\030\003 \001(\r\022+\n\ngameconfig\030\004 \001(\0132\027.Club.pb_tag" | |||||
"TableConfig\"r\n\033PB_CS_S_Club_Action_Ack1A" | |||||
"dd\022\016\n\006Result\030\001 \001(\r\0222\n\013AutoAddInfo\030\002 \001(\0132" | |||||
"\035.Club.PB_CS_C_ClubAutoAddInfo\022\017\n\007Messag" | |||||
"e\030\003 \001(\t\"@\n\024PB_CS_C_ClubExploits\022\020\n\010dwClu" | |||||
"bID\030\001 \001(\r\022\026\n\016PrivateTableID\030\002 \001(\r\"p\n\025PB_" | |||||
"CS_C_ClubPlaygames\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005" | |||||
"wType\030\002 \001(\r\022\022\n\nStartIndex\030\003 \001(\r\022\016\n\006mCoun" | |||||
"t\030\004 \001(\r\022\022\n\nwDateCount\030\005 \001(\r\"\205\001\n\030PB_CS_S_" | |||||
"tagClubPlaygames\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mC" | |||||
"ount\030\002 \001(\r\022\022\n\nszUserName\030\003 \001(\t\022\021\n\tszHead" | |||||
"Img\030\004 \001(\t\022\022\n\nwDateCount\030\005 \001(\r\022\014\n\004temp\030\006 " | |||||
"\001(\r\"K\n\024PB_CS_C_ClubIntegral\022\020\n\010dwClubID\030" | |||||
"\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\nwDateCount\030\003 \001(\r" | |||||
"\"\224\001\n\027PB_CS_S_tagClubIntegral\022\020\n\010dwUserID" | |||||
"\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022" | |||||
"\n\nszUserName\030\004 \001(\t\022\021\n\tszHeadImg\030\005 \001(\t\022\022\n" | |||||
"\nwDateCount\030\006 \001(\r\022\014\n\004temp\030\007 \001(\r\">\n\030PB_CS" | |||||
"_Club_Make_A_Sample\022\020\n\010dwClubID\030\001 \001(\r\022\020\n" | |||||
"\010IsSample\030\002 \001(\rb\006proto3" | |||||
======= | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n*Source/MessageDef/Pb_ClubInformation.p" | |||||
"roto\022\004Club\"7\n\020PB_CS_C_ClubList\022\023\n\013wStart" | |||||
"Index\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"\272\002\n\021pb_tagTa" | |||||
"bleConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\021\n\twPlayRu" | |||||
"le\030\002 \001(\r\022\023\n\013wMaxFanRule\030\003 \001(\r\022\021\n\twMaxSco" | |||||
"re\030\004 \001(\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\025\n\rwHad" | |||||
"PlayCount\030\006 \001(\r\022\023\n\013zmExtraRule\030\007 \001(\r\022\017\n\007" | |||||
"dghRule\030\010 \001(\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017" | |||||
"\n\007bDuoLai\030\n \001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tm" | |||||
"p1\030\014 \001(\r\022\014\n\004tmp2\030\r \001(\r\022\014\n\004tmp3\030\016 \001(\r\022\014\n\004" | |||||
"tmp4\030\017 \001(\r\022\014\n\004tmp5\030\020 \001(\r\"n\n\024PB_CS_S_Club" | |||||
"List_Ack\022\022\n\nwNewsCount\030\001 \001(\r\022\022\n\nwClubCou" | |||||
"nt\030\002 \001(\r\022.\n\016csGameClubInfo\030\003 \003(\0132\026.Club." | |||||
"PB_CS_C_ClubInfo\":\n\023PB_CS_C_ClubMessage\022" | |||||
"\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"H\n\016" | |||||
"pb_MessageInfo\022\r\n\005dType\030\001 \001(\r\022\021\n\tszConte" | |||||
"nt\030\002 \001(\t\022\024\n\014dtActionTime\030\003 \001(\r\"T\n\027PB_CS_" | |||||
"S_ClubMessage_Ack\022\016\n\006wCount\030\001 \001(\r\022)\n\013Mes" | |||||
"sageInfo\030\002 \003(\0132\024.Club.pb_MessageInfo\"x\n\022" | |||||
"PB_CS_C_ClubRecord\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013" | |||||
"wStartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\023\n\013dtS" | |||||
"tartTime\030\004 \001(\r\022\026\n\016dwPrivatetable\030\005 \001(\r\"$" | |||||
"\n\rpb_PlayerName\022\023\n\013PlayerName2\030\001 \001(\t\"\264\001\n" | |||||
"\022PB_CS_S_RecordInfo\022\021\n\tdwTableID\030\001 \001(\r\022\017" | |||||
"\n\007cbJuShu\030\002 \001(\r\022\020\n\010cbPayWay\030\003 \001(\r\022\026\n\016dwT" | |||||
"ableOwnerID\030\004 \001(\r\022\024\n\014dtCreateTime\030\005 \001(\r\022" | |||||
"\020\n\010PlayerID\030\006 \003(\r\022(\n\013PlayerName1\030\007 \003(\0132\023" | |||||
".Club.pb_PlayerName\"\\\n\024PB_CS_S_RecordInf" | |||||
"oEX\022(\n\006Record\030\001 \001(\0132\030.Club.PB_CS_S_Recor" | |||||
"dInfo\022\r\n\005Score\030\002 \003(\022\022\013\n\003Tmp\030\003 \003(\r\"\227\001\n\031PB" | |||||
"_CS_S_ClubRecord_Ack_EX\022\016\n\006wCount\030\001 \001(\r\022" | |||||
"\024\n\014dwTableCount\030\002 \001(\r\022\020\n\010dwZunShi\030\003 \001(\r\022" | |||||
"\020\n\010dwClubID\030\004 \001(\r\0220\n\014csRecordInfo\030\005 \003(\0132" | |||||
"\032.Club.PB_CS_S_RecordInfoEX\"\304\002\n\020PB_CS_C_" | |||||
"ClubInfo\022\020\n\010dwClubID\030\001 \001(\r\022\022\n\nszClubName" | |||||
"\030\002 \001(\t\022\021\n\tcbIsOwner\030\003 \001(\r\022\021\n\twTotalNum\030\004" | |||||
" \001(\r\022\025\n\rwWaitTableNum\030\005 \001(\r\022\022\n\nwOnLineNu" | |||||
"m\030\006 \001(\r\022\024\n\014wWaitUserNum\030\007 \001(\r\022\021\n\tdwOwner" | |||||
"ID\030\010 \001(\r\022\022\n\nszHostName\030\t \001(\t\022\021\n\tszHeadUr" | |||||
"l\030\n \001(\t\022\r\n\005temp1\030\013 \001(\r\022\r\n\005temp2\030\014 \001(\r\022\r\n" | |||||
"\005temp3\030\r \001(\r\022\r\n\005temp4\030\016 \001(\r\022-\n\014csGameCon" | |||||
"fig\030\017 \001(\0132\027.Club.pb_tagTableConfig\"(\n\024PB" | |||||
"_CS_C_Club_Action1\022\020\n\010dwClubID\030\001 \001(\r\";\n\030" | |||||
"PB_CS_S_Club_Action_Ack1\022\016\n\006Result\030\001 \001(\r" | |||||
"\022\017\n\007Message\030\002 \001(\t\"e\n\030PB_CS_S_Club_Action" | |||||
"_Ack2\022\016\n\006Result\030\001 \001(\r\022(\n\010ClubInfo\030\002 \001(\0132" | |||||
"\026.Club.PB_CS_C_ClubInfo\022\017\n\007Message\030\003 \001(\t" | |||||
"\"M\n\024PB_CS_C_Club_Action2\022\020\n\010dwClubID\030\001 \001" | |||||
"(\r\022\020\n\010dwUserID\030\002 \001(\r\022\021\n\tcbIsAgree\030\003 \001(\r\"" | |||||
"]\n\030PB_CS_S_Club_Action_Ack3\022\017\n\007wClubID\030\001" | |||||
" \001(\r\022\016\n\006Result\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\017\n" | |||||
"\007cbAgree\030\004 \001(\r\"]\n\024PB_CS_C_ClubOnLineEx\022\020" | |||||
"\n\010dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n" | |||||
"\006wCount\030\003 \001(\r\022\016\n\006cbType\030\004 \001(\r\"\247\001\n\030PB_CS_" | |||||
"S_ClubOnLine_AckEx\022\020\n\010dwClubID\030\001 \001(\r\022\024\n\014" | |||||
"wQueTableNum\030\002 \001(\r\022\025\n\rwWaitTableNum\030\003 \001(" | |||||
"\r\022\025\n\rwPlayTableNmu\030\004 \001(\r\022\014\n\004temp\030\005 \001(\r\022\026" | |||||
"\n\016wtotalTableNum\030\006 \001(\r\022\017\n\007tableID\030\007 \003(\r\"" | |||||
"s\n\031PB_CS_S_Club_Notify_ACKEX\022\020\n\010newsFalg" | |||||
"\030\001 \001(\r\022\014\n\004Temp\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\020\n" | |||||
"\010dwClubID\030\004 \001(\r\022\023\n\013dwUserCount\030\005 \001(\r\"j\n\021" | |||||
"PB_CS_C_ClubUser2\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013w" | |||||
"StartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\016\n\006cbKi" | |||||
"nd\030\004 \001(\r\022\016\n\006dwTemp\030\005 \001(\r\"\216\001\n\022PB_CS_S_Mem" | |||||
"berInfo\022\020\n\010BangMaID\030\001 \001(\r\022\017\n\007cbStaus\030\002 \001" | |||||
"(\r\022\016\n\006isHost\030\003 \001(\r\022\020\n\010isOnline\030\004 \001(\r\022\020\n\010" | |||||
"dwUserID\030\005 \001(\r\022\016\n\006szName\030\006 \001(\t\022\021\n\tszHead" | |||||
"Url\030\007 \001(\t\"\226\001\n\025PB_CS_S_ClubUser2_Ack\022\016\n\006c" | |||||
"bKind\030\001 \001(\r\022\013\n\003tmp\030\002 \001(\r\022\016\n\006cbHost\030\003 \001(\r" | |||||
"\022\020\n\010dwClubID\030\004 \001(\r\022\016\n\006wCount\030\005 \001(\r\022.\n\014cs" | |||||
"MemberInfo\030\006 \003(\0132\030.Club.PB_CS_S_MemberIn" | |||||
"fo\"8\n\024PB_CS_C_ClubProtocol\022\020\n\010dwClubID\030\001" | |||||
" \001(\r\022\016\n\006dwTemp\030\002 \001(\r\"N\n\031PB_CS_S_ClubProt" | |||||
"ocolAgree\022\020\n\010dwClubID\030\001 \001(\r\022\017\n\007cbAgree\030\002" | |||||
" \001(\r\022\016\n\006dwTemp\030\003 \001(\r\"K\n\026PB_CS_S_ClubActi" | |||||
"onAck1\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006Result\030\002 \001(\r" | |||||
"\022\017\n\007Message\030\003 \001(\t\"W\n\022PB_CS_C_ClubNotice\022" | |||||
"\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030\002 \001(\r\022\016\n\006dwT" | |||||
"emp\030\003 \001(\r\022\017\n\007Message\030\004 \001(\t\"l\n\025PB_CS_S_Cl" | |||||
"ubNoticeACK\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030" | |||||
"\002 \001(\r\022\016\n\006dwTemp\030\003 \001(\r\022\020\n\010cbResult\030\004 \001(\r\022" | |||||
"\017\n\007Message\030\005 \001(\t\"I\n\020PB_CS_C_ClubUser\022\020\n\010" | |||||
"dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n\006w" | |||||
"Count\030\003 \001(\r\"x\n\024PB_CS_S_ClubUser_Ack\022\016\n\006c" | |||||
"bHost\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\016\n\006wCount\030" | |||||
"\003 \001(\r\022.\n\014csMemberInfo\030\004 \003(\0132\030.Club.PB_CS" | |||||
"_S_MemberInfo\"N\n\027PB_CS_C_ClubOnLineTable" | |||||
"\022\016\n\006cbType\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\021\n\tdw" | |||||
"TableID\030\003 \001(\r\"\273\002\n\017pb_RoomListInfo\022\016\n\006szN" | |||||
"ame\030\001 \001(\t\022\022\n\ndwServerID\030\002 \001(\r\022\014\n\004szIp\030\003 " | |||||
"\001(\t\022\017\n\007bDuoLai\030\004 \001(\r\022\021\n\twFengDing\030\005 \001(\r\022" | |||||
"\014\n\004tmp1\030\006 \001(\r\022\014\n\004tmp2\030\007 \001(\r\022\014\n\004tmp6\030\010 \003(" | |||||
"\022\022\r\n\005wPort\030\t \001(\r\022\024\n\014dwRoomNumber\030\n \001(\r\022\017" | |||||
"\n\007dwDiFen\030\013 \001(\r\022\017\n\007dwJuShu\030\014 \001(\r\022\026\n\016bRoo" | |||||
"mCreatePay\030\r \001(\r\022\017\n\007bFanGua\030\016 \001(\r\022\016\n\006bWa" | |||||
"nFa\030\017 \001(\r\022\014\n\004tmp3\030\020 \001(\r\022\014\n\004tmp4\030\021 \001(\r\022\014\n" | |||||
"\004tmp5\030\022 \001(\r\"V\n\034PB_CS_S_ClubOnLineTableCf" | |||||
"Ack\022\021\n\tdwTableID\030\001 \001(\r\022#\n\004Room\030\002 \001(\0132\025.C" | |||||
"lub.pb_RoomListInfo\"D\n\rpb_PlayerInfo\022\020\n\010" | |||||
"dwUserID\030\001 \001(\r\022\016\n\006szName\030\002 \001(\t\022\021\n\tszHead" | |||||
"Url\030\003 \001(\t\"{\n\032PB_CS_S_ClubOnLineTableAck\022" | |||||
"\021\n\tdwTableID\030\001 \001(\r\022\016\n\006wJushu\030\002 \001(\r\022\023\n\013wT" | |||||
"ableState\030\003 \001(\r\022%\n\010Userinfo\030\004 \003(\0132\023.Club" | |||||
".pb_PlayerInfo\"E\n\024PB_CS_S_Table_Notify\022\014" | |||||
"\n\004type\030\001 \001(\r\022\017\n\007tableID\030\002 \001(\r\022\016\n\006clubID\030" | |||||
"\003 \001(\r\"\324\001\n\035PB_CS_S_TableOtherInfo_Notify\022" | |||||
"\016\n\006ClubID\030\001 \001(\r\022\014\n\004Type\030\002 \001(\r\022\024\n\014totalUs" | |||||
"erNum\030\003 \001(\004\022\025\n\ronlineUserNum\030\004 \001(\004\022\025\n\rto" | |||||
"talTableNum\030\005 \001(\004\022\021\n\tnewMsgNum\030\006 \001(\r\022\022\n\n" | |||||
"newUserNum\030\007 \001(\r\022\024\n\014waitTableNum\030\010 \001(\r\022\024" | |||||
"\n\014playTableNum\030\t \001(\r\">\n\030PB_CS_C_ClubDiss" | |||||
"olveRoom\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010dwRoomID\030\002" | |||||
" \001(\r\"}\n\027PB_CS_C_ClubAutoAddInfo\022\020\n\010dwClu" | |||||
"bID\030\001 \001(\r\022\021\n\tcbWanfaId\030\002 \001(\r\022\020\n\010cbStatus" | |||||
"\030\003 \001(\r\022+\n\ngameconfig\030\004 \001(\0132\027.Club.pb_tag" | |||||
"TableConfig\"r\n\033PB_CS_S_Club_Action_Ack1A" | |||||
"dd\022\016\n\006Result\030\001 \001(\r\0222\n\013AutoAddInfo\030\002 \001(\0132" | |||||
"\035.Club.PB_CS_C_ClubAutoAddInfo\022\017\n\007Messag" | |||||
"e\030\003 \001(\t\"@\n\024PB_CS_C_ClubExploits\022\020\n\010dwClu" | |||||
"bID\030\001 \001(\r\022\026\n\016PrivateTableID\030\002 \001(\r\"p\n\025PB_" | |||||
"CS_C_ClubPlaygames\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005" | |||||
"wType\030\002 \001(\r\022\022\n\nStartIndex\030\003 \001(\r\022\016\n\006mCoun" | |||||
"t\030\004 \001(\r\022\022\n\nwDateCount\030\005 \001(\r\"a\n\026PB_CS_tag" | |||||
"ClubPlaygames\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCoun" | |||||
"t\030\002 \001(\r\022\022\n\nszUserName\030\003 \001(\t\022\021\n\tszHeadImg" | |||||
"\030\004 \001(\t\"m\n\030PB_CS_S_tagClubPlaygames\022\022\n\nwD" | |||||
"ateCount\030\001 \001(\r\022\014\n\004temp\030\002 \001(\r\022/\n\tPlaygame" | |||||
"s\030\003 \003(\0132\034.Club.PB_CS_tagClubPlaygames\"K\n" | |||||
"\024PB_CS_C_ClubIntegral\022\020\n\010dwClubID\030\001 \001(\r\022" | |||||
"\r\n\005wType\030\002 \001(\r\022\022\n\nwDateCount\030\003 \001(\r\"p\n\025PB" | |||||
"_CS_tagClubIntegral\022\020\n\010dwUserID\030\001 \001(\r\022\016\n" | |||||
"\006mCount\030\002 \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022\n\nszUserN" | |||||
"ame\030\004 \001(\t\022\021\n\tszHeadImg\030\005 \001(\t\"j\n\027PB_CS_S_" | |||||
"tagClubIntegral\022\022\n\nwDateCount\030\001 \001(\r\022\014\n\004t" | |||||
"emp\030\002 \001(\r\022-\n\010Integral\030\003 \003(\0132\033.Club.PB_CS" | |||||
"_tagClubIntegral\">\n\030PB_CS_Club_Make_A_Sa" | |||||
"mple\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010IsSample\030\002 \001(\r" | |||||
"b\006proto3" | |||||
>>>>>>> .r273 | |||||
"unt\030\005 \001(\r\"a\n\026PB_CS_tagClubPlaygames\022\020\n\010d" | |||||
"wUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\022\n\nszUserN" | |||||
"ame\030\003 \001(\t\022\021\n\tszHeadImg\030\004 \001(\t\"m\n\030PB_CS_S_" | |||||
"tagClubPlaygames\022\022\n\nwDateCount\030\001 \001(\r\022\014\n\004" | |||||
"temp\030\002 \001(\r\022/\n\tPlaygames\030\003 \003(\0132\034.Club.PB_" | |||||
"CS_tagClubPlaygames\"K\n\024PB_CS_C_ClubInteg" | |||||
"ral\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\n" | |||||
"wDateCount\030\003 \001(\r\"p\n\025PB_CS_tagClubIntegra" | |||||
"l\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\016\n\006m" | |||||
"JiFen\030\003 \001(\022\022\022\n\nszUserName\030\004 \001(\t\022\021\n\tszHea" | |||||
"dImg\030\005 \001(\t\"j\n\027PB_CS_S_tagClubIntegral\022\022\n" | |||||
"\nwDateCount\030\001 \001(\r\022\014\n\004temp\030\002 \001(\r\022-\n\010Integ" | |||||
"ral\030\003 \003(\0132\033.Club.PB_CS_tagClubIntegral\">" | |||||
"\n\030PB_CS_Club_Make_A_Sample\022\020\n\010dwClubID\030\001" | |||||
" \001(\r\022\020\n\010IsSample\030\002 \001(\rb\006proto3" | |||||
; | ; | ||||
static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fClubInformation_2eproto_deps[1] = { | static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fClubInformation_2eproto_deps[1] = { | ||||
}; | }; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fClubInformation_2eproto_sccs[46] = { | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fClubInformation_2eproto_sccs[48] = { | |||||
&scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_PB_CS_C_ClubDissolveRoom_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_C_ClubDissolveRoom_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_PB_CS_C_ClubExploits_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_C_ClubExploits_Pb_5fClubInformation_2eproto.base, | ||||
@@ -1983,136 +1651,21 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_ | |||||
&scc_info_PB_CS_S_Table_Notify_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_S_Table_Notify_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base, | &scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto.base, | &scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto.base, | &scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto.base, | &scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto.base, | &scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto.base, | ||||
&scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto.base, | &scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto.base, | ||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs[46] = { | |||||
&scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubDissolveRoom_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubExploits_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubList_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubMessage_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubNotice_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubOnLineEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubOnLineTable_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubProtocol_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubRecord_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubUser_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubUser2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_Club_Action1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_Club_Action2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_Club_Make_A_Sample_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubActionAck1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubList_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubMessage_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubNoticeACK_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLineTableAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLineTableCfAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLine_AckEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubProtocolAgree_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubRecord_Ack_EX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubUser2_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubUser_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack1Add_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack3_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Notify_ACKEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_TableOtherInfo_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Table_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs[48] = { | |||||
&scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubDissolveRoom_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubExploits_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubList_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubMessage_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubNotice_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubOnLineEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubOnLineTable_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubProtocol_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubRecord_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubUser_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_ClubUser2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_Club_Action1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_C_Club_Action2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_Club_Make_A_Sample_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubActionAck1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubList_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubMessage_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubNoticeACK_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLineTableAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLineTableCfAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubOnLine_AckEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubProtocolAgree_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubRecord_Ack_EX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubUser2_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_ClubUser_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack1Add_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Action_Ack3_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Club_Notify_ACKEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_TableOtherInfo_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_Table_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
&scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, | |||||
>>>>>>> .r273 | |||||
}; | }; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fClubInformation_2eproto_once; | static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fClubInformation_2eproto_once; | ||||
static bool descriptor_table_Pb_5fClubInformation_2eproto_initialized = false; | static bool descriptor_table_Pb_5fClubInformation_2eproto_initialized = false; | ||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fClubInformation_2eproto = { | const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fClubInformation_2eproto = { | ||||
&descriptor_table_Pb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Pb_5fClubInformation_2eproto, "Pb_ClubInformation.proto", 5325, | |||||
&descriptor_table_Pb_5fClubInformation_2eproto_once, descriptor_table_Pb_5fClubInformation_2eproto_sccs, descriptor_table_Pb_5fClubInformation_2eproto_deps, 46, 0, | |||||
&descriptor_table_Pb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Pb_5fClubInformation_2eproto, "Pb_ClubInformation.proto", 5470, | |||||
&descriptor_table_Pb_5fClubInformation_2eproto_once, descriptor_table_Pb_5fClubInformation_2eproto_sccs, descriptor_table_Pb_5fClubInformation_2eproto_deps, 48, 0, | |||||
schemas, file_default_instances, TableStruct_Pb_5fClubInformation_2eproto::offsets, | schemas, file_default_instances, TableStruct_Pb_5fClubInformation_2eproto::offsets, | ||||
file_level_metadata_Pb_5fClubInformation_2eproto, 46, file_level_enum_descriptors_Pb_5fClubInformation_2eproto, file_level_service_descriptors_Pb_5fClubInformation_2eproto, | |||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once; | |||||
static bool descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized = false; | |||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = { | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, "Source/MessageDef/Pb_ClubInformation.proto", 5343, | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_deps, 46, 0, | |||||
schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto::offsets, | |||||
file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, 46, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once; | |||||
static bool descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized = false; | |||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = { | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, "Source/MessageDef/Pb_ClubInformation.proto", 5488, | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_deps, 48, 0, | |||||
schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto::offsets, | |||||
file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, 48, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, | |||||
>>>>>>> .r273 | |||||
file_level_metadata_Pb_5fClubInformation_2eproto, 48, file_level_enum_descriptors_Pb_5fClubInformation_2eproto, file_level_service_descriptors_Pb_5fClubInformation_2eproto, | |||||
}; | }; | ||||
// Force running AddDescriptors() at dynamic initialization time. | // Force running AddDescriptors() at dynamic initialization time. | ||||
@@ -14303,16 +13856,8 @@ PB_CS_tagClubPlaygames::PB_CS_tagClubPlaygames(const PB_CS_tagClubPlaygames& fro | |||||
// @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubPlaygames) | // @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubPlaygames) | ||||
} | } | ||||
<<<<<<< .mine | |||||
void PB_CS_S_tagClubPlaygames::SharedCtor() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
||||||| .r248 | |||||
void PB_CS_S_tagClubPlaygames::SharedCtor() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
======= | |||||
void PB_CS_tagClubPlaygames::SharedCtor() { | void PB_CS_tagClubPlaygames::SharedCtor() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
::memset(&dwuserid_, 0, static_cast<size_t>( | ::memset(&dwuserid_, 0, static_cast<size_t>( | ||||
@@ -14333,16 +13878,8 @@ void PB_CS_tagClubPlaygames::SharedDtor() { | |||||
void PB_CS_tagClubPlaygames::SetCachedSize(int size) const { | void PB_CS_tagClubPlaygames::SetCachedSize(int size) const { | ||||
_cached_size_.Set(size); | _cached_size_.Set(size); | ||||
} | } | ||||
<<<<<<< .mine | |||||
const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
||||||| .r248 | |||||
const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
======= | |||||
const PB_CS_tagClubPlaygames& PB_CS_tagClubPlaygames::default_instance() { | const PB_CS_tagClubPlaygames& PB_CS_tagClubPlaygames::default_instance() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
return *internal_default_instance(); | return *internal_default_instance(); | ||||
} | } | ||||
@@ -14604,7 +14141,7 @@ PB_CS_S_tagClubPlaygames::PB_CS_S_tagClubPlaygames(const PB_CS_S_tagClubPlaygame | |||||
} | } | ||||
void PB_CS_S_tagClubPlaygames::SharedCtor() { | void PB_CS_S_tagClubPlaygames::SharedCtor() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
::memset(&wdatecount_, 0, static_cast<size_t>( | ::memset(&wdatecount_, 0, static_cast<size_t>( | ||||
reinterpret_cast<char*>(&temp_) - | reinterpret_cast<char*>(&temp_) - | ||||
reinterpret_cast<char*>(&wdatecount_)) + sizeof(temp_)); | reinterpret_cast<char*>(&wdatecount_)) + sizeof(temp_)); | ||||
@@ -14622,7 +14159,7 @@ void PB_CS_S_tagClubPlaygames::SetCachedSize(int size) const { | |||||
_cached_size_.Set(size); | _cached_size_.Set(size); | ||||
} | } | ||||
const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { | const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); | |||||
return *internal_default_instance(); | return *internal_default_instance(); | ||||
} | } | ||||
@@ -15098,16 +14635,8 @@ PB_CS_tagClubIntegral::PB_CS_tagClubIntegral(const PB_CS_tagClubIntegral& from) | |||||
// @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubIntegral) | // @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubIntegral) | ||||
} | } | ||||
<<<<<<< .mine | |||||
void PB_CS_S_tagClubIntegral::SharedCtor() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
||||||| .r248 | |||||
void PB_CS_S_tagClubIntegral::SharedCtor() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
======= | |||||
void PB_CS_tagClubIntegral::SharedCtor() { | void PB_CS_tagClubIntegral::SharedCtor() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
::memset(&dwuserid_, 0, static_cast<size_t>( | ::memset(&dwuserid_, 0, static_cast<size_t>( | ||||
@@ -15128,16 +14657,8 @@ void PB_CS_tagClubIntegral::SharedDtor() { | |||||
void PB_CS_tagClubIntegral::SetCachedSize(int size) const { | void PB_CS_tagClubIntegral::SetCachedSize(int size) const { | ||||
_cached_size_.Set(size); | _cached_size_.Set(size); | ||||
} | } | ||||
<<<<<<< .mine | |||||
const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
||||||| .r248 | |||||
const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
======= | |||||
const PB_CS_tagClubIntegral& PB_CS_tagClubIntegral::default_instance() { | const PB_CS_tagClubIntegral& PB_CS_tagClubIntegral::default_instance() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
>>>>>>> .r273 | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
return *internal_default_instance(); | return *internal_default_instance(); | ||||
} | } | ||||
@@ -15423,7 +14944,7 @@ PB_CS_S_tagClubIntegral::PB_CS_S_tagClubIntegral(const PB_CS_S_tagClubIntegral& | |||||
} | } | ||||
void PB_CS_S_tagClubIntegral::SharedCtor() { | void PB_CS_S_tagClubIntegral::SharedCtor() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
::memset(&wdatecount_, 0, static_cast<size_t>( | ::memset(&wdatecount_, 0, static_cast<size_t>( | ||||
reinterpret_cast<char*>(&temp_) - | reinterpret_cast<char*>(&temp_) - | ||||
reinterpret_cast<char*>(&wdatecount_)) + sizeof(temp_)); | reinterpret_cast<char*>(&wdatecount_)) + sizeof(temp_)); | ||||
@@ -15441,7 +14962,7 @@ void PB_CS_S_tagClubIntegral::SetCachedSize(int size) const { | |||||
_cached_size_.Set(size); | _cached_size_.Set(size); | ||||
} | } | ||||
const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { | const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); | |||||
return *internal_default_instance(); | return *internal_default_instance(); | ||||
} | } | ||||
@@ -7771,7 +7771,7 @@ class PB_CS_tagClubPlaygames : | |||||
::PROTOBUF_NAMESPACE_ID::uint32 dwuserid_; | ::PROTOBUF_NAMESPACE_ID::uint32 dwuserid_; | ||||
::PROTOBUF_NAMESPACE_ID::uint32 mcount_; | ::PROTOBUF_NAMESPACE_ID::uint32 mcount_; | ||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | ||||
friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
friend struct ::TableStruct_Pb_5fClubInformation_2eproto; | |||||
}; | }; | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -7870,8 +7870,8 @@ class PB_CS_S_tagClubPlaygames : | |||||
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ||||
private: | private: | ||||
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto); | |||||
return ::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fClubInformation_2eproto); | |||||
return ::descriptor_table_Pb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
} | } | ||||
public: | public: | ||||
@@ -8266,7 +8266,7 @@ class PB_CS_tagClubIntegral : | |||||
::PROTOBUF_NAMESPACE_ID::uint32 mcount_; | ::PROTOBUF_NAMESPACE_ID::uint32 mcount_; | ||||
::PROTOBUF_NAMESPACE_ID::int64 mjifen_; | ::PROTOBUF_NAMESPACE_ID::int64 mjifen_; | ||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | ||||
friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; | |||||
friend struct ::TableStruct_Pb_5fClubInformation_2eproto; | |||||
}; | }; | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -8365,8 +8365,8 @@ class PB_CS_S_tagClubIntegral : | |||||
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ||||
private: | private: | ||||
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto); | |||||
return ::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fClubInformation_2eproto); | |||||
return ::descriptor_table_Pb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
} | } | ||||
public: | public: | ||||
@@ -108,12 +108,7 @@ static void InitDefaultsscc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2epro | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto = | ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto = | ||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto}, {}}; | {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto}, {}}; | ||||
<<<<<<< .mine | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto() { | |||||
||||||| .r248 | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { | |||||
======= | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto() { | |||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
{ | { | ||||
@@ -124,11 +119,10 @@ static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef | |||||
::LogonServer::PB_CS_S_LogonCheckVerifCode::InitAsDefaultInstance(); | ::LogonServer::PB_CS_S_LogonCheckVerifCode::InitAsDefaultInstance(); | ||||
} | } | ||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto}, {}}; | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto = | |||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto}, {}}; | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { | |||||
>>>>>>> .r273 | |||||
static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto() { | |||||
GOOGLE_PROTOBUF_VERIFY_VERSION; | GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
{ | { | ||||
@@ -184,19 +178,9 @@ static void InitDefaultsscc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto( | |||||
::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto = | ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto = | ||||
{{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto}, {}}; | {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto}, {}}; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fLogonServer_2eproto[8]; | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fLogonServer_2eproto[9]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fLogonServer_2eproto = nullptr; | static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fLogonServer_2eproto = nullptr; | ||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fLogonServer_2eproto = nullptr; | static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fLogonServer_2eproto = nullptr; | ||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[8]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[9]; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; | |||||
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; | |||||
>>>>>>> .r273 | |||||
const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fLogonServer_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { | const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fLogonServer_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { | ||||
~0u, // no _has_bits_ | ~0u, // no _has_bits_ | ||||
@@ -344,207 +328,74 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = | |||||
reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::LogonServer::_PB_CS_S_tagGameServer_default_instance_), | reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::LogonServer::_PB_CS_S_tagGameServer_default_instance_), | ||||
}; | }; | ||||
<<<<<<< .mine | |||||
const char descriptor_table_protodef_Pb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | const char descriptor_table_protodef_Pb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | ||||
"\n\024Pb_LogonServer.proto\022\013LogonServer\"\251\001\n\025" | |||||
"\n\024Pb_LogonServer.proto\022\013LogonServer\"\274\001\n\025" | |||||
"PB_CS_C_LogonAccounts\022\021\n\twModuleID\030\001 \001(\r" | "PB_CS_C_LogonAccounts\022\021\n\twModuleID\030\001 \001(\r" | ||||
"\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType" | "\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType" | ||||
"\030\003 \001(\r\022\022\n\nbLogonType\030\004 \001(\r\022\022\n\nszAccounts" | "\030\003 \001(\r\022\022\n\nbLogonType\030\004 \001(\r\022\022\n\nszAccounts" | ||||
"\030\005 \001(\t\022\022\n\nszPassword\030\006 \001(\t\022\023\n\013szMachineI" | "\030\005 \001(\t\022\022\n\nszPassword\030\006 \001(\t\022\023\n\013szMachineI" | ||||
"D\030\007 \001(\t\"\304\002\n\024PB_CS_S_LogonSuccess\022\022\n\ndwCu" | |||||
"stomID\030\001 \001(\r\022\020\n\010dwUserID\030\002 \001(\r\022\020\n\010dwGame" | |||||
"ID\030\003 \001(\r\022\024\n\014dwExperience\030\004 \001(\r\022\024\n\014dwLove" | |||||
"Liness\030\005 \001(\r\022\022\n\nlUserScore\030\006 \001(\021\022\022\n\nlUse" | |||||
"rIngot\030\007 \001(\021\022\023\n\013lUserInsure\030\010 \001(\021\022\022\n\ndUs" | |||||
"erBeans\030\t \001(\021\022\017\n\007wFaceID\030\n \001(\r\022\020\n\010cbGend" | |||||
"er\030\013 \001(\r\022\027\n\017cbInsureEnabled\030\014 \001(\r\022\022\n\nszN" | |||||
"ickName\030\r \001(\t\022\025\n\rszDynamicPass\030\016 \001(\t\022\020\n\010" | |||||
"BingDing\030\017 \001(\r\"E\n\024PB_CS_S_LogonFailure\022\023" | |||||
"\n\013lResultCode\030\001 \001(\022\022\030\n\020szDescribeString\030" | |||||
"\002 \001(\t\"@\n\033PB_CS_C_LogonCheckVerifCode\022\017\n\007" | |||||
"bResult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\"\347\001\n\030PB_C" | |||||
"S_C_RegisterAccounts\022\021\n\twModuleID\030\001 \001(\r\022" | |||||
"\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030" | |||||
"\003 \001(\r\022\023\n\013szLogonPass\030\004 \001(\t\022\017\n\007wFaceID\030\005 " | |||||
"\001(\r\022\020\n\010cbGender\030\006 \001(\r\022\022\n\nszAccounts\030\007 \001(" | |||||
"\t\022\022\n\nszNickName\030\010 \001(\t\022\023\n\013szMachineID\030\t \001" | |||||
"(\t\022\025\n\rszMobilePhone\030\n \001(\t\"\330\002\n\034PB_CS_C_Lo" | |||||
"gonOtherPlatformEx\022\021\n\twModuleID\030\001 \001(\r\022\026\n" | |||||
"\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 " | |||||
"\001(\r\022\020\n\010cbGender\030\004 \001(\r\022\024\n\014cbPlatformID\030\005 " | |||||
"\001(\r\022\021\n\tszUserUin\030\006 \001(\t\022\022\n\nszNickName\030\007 \001" | |||||
"(\t\022\026\n\016szCompellation\030\010 \001(\t\022\023\n\013szMachineI" | |||||
"D\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\022\021\n\tszHead" | |||||
"Url\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022\022\023\n\013isSim" | |||||
"ulator\030\016 \001(\r\022\023\n\013networkType\030\017 \001(\r\022\021\n\tdia" | |||||
"nliang\030\020 \001(\r\")\n\024PB_CS_S_UserServerID\022\021\n\t" | |||||
"wServerID\030\001 \001(\r\"\221\003\n\025PB_CS_S_tagGameServe" | |||||
"r\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007wNodeID\030\002 \001(\r\022\017\n\007w" | |||||
"SortID\030\003 \001(\r\022\021\n\twServerID\030\004 \001(\r\022\023\n\013wServ" | |||||
"erKind\030\005 \001(\r\022\023\n\013wServerType\030\006 \001(\r\022\023\n\013wSe" | |||||
"rverPort\030\007 \001(\r\022\022\n\nlCellScore\030\010 \001(\022\022\023\n\013lE" | |||||
"nterScore\030\t \001(\022\022\024\n\014dwServerRule\030\n \001(\022\022\025\n" | |||||
"\rdwOnLineCount\030\013 \001(\r\022\027\n\017wTableFullCount\030" | |||||
"\014 \001(\r\022\031\n\021wTableOnlineCount\030\r \001(\r\022\023\n\013dwFu" | |||||
"llCount\030\016 \001(\r\022\024\n\014szServerAddr\030\017 \001(\t\022\024\n\014s" | |||||
"zServerName\030\020 \001(\t\022\022\n\ndwLiveTime\030\021 \001(\022\022\024\n" | |||||
"\014wServerLevel\030\022 \001(\rb\006proto3" | |||||
||||||| .r248 | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n&Source/MessageDef/Pb_LogonServer.proto" | |||||
"\022\013LogonServer\"\251\001\n\025PB_CS_C_LogonAccounts\022" | |||||
"\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001" | |||||
"(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\022\n\nbLogonType\030\004" | |||||
" \001(\r\022\022\n\nszAccounts\030\005 \001(\t\022\022\n\nszPassword\030\006" | |||||
" \001(\t\022\023\n\013szMachineID\030\007 \001(\t\"\304\002\n\024PB_CS_S_Lo" | |||||
"gonSuccess\022\022\n\ndwCustomID\030\001 \001(\r\022\020\n\010dwUser" | |||||
"ID\030\002 \001(\r\022\020\n\010dwGameID\030\003 \001(\r\022\024\n\014dwExperien" | |||||
"ce\030\004 \001(\r\022\024\n\014dwLoveLiness\030\005 \001(\r\022\022\n\nlUserS" | |||||
"core\030\006 \001(\021\022\022\n\nlUserIngot\030\007 \001(\021\022\023\n\013lUserI" | |||||
"nsure\030\010 \001(\021\022\022\n\ndUserBeans\030\t \001(\021\022\017\n\007wFace" | |||||
"ID\030\n \001(\r\022\020\n\010cbGender\030\013 \001(\r\022\027\n\017cbInsureEn" | |||||
"abled\030\014 \001(\r\022\022\n\nszNickName\030\r \001(\t\022\025\n\rszDyn" | |||||
"amicPass\030\016 \001(\t\022\020\n\010BingDing\030\017 \001(\r\"E\n\024PB_C" | |||||
"S_S_LogonFailure\022\023\n\013lResultCode\030\001 \001(\022\022\030\n" | |||||
"\020szDescribeString\030\002 \001(\t\"@\n\033PB_CS_C_Logon" | |||||
"CheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010Phone" | |||||
"Num\030\002 \001(\t\"\347\001\n\030PB_CS_C_RegisterAccounts\022\021" | |||||
"\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(" | |||||
"\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\023\n\013szLogonPass\030\004" | |||||
" \001(\t\022\017\n\007wFaceID\030\005 \001(\r\022\020\n\010cbGender\030\006 \001(\r\022" | |||||
"\022\n\nszAccounts\030\007 \001(\t\022\022\n\nszNickName\030\010 \001(\t\022" | |||||
"\023\n\013szMachineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n " | |||||
"\001(\t\"\330\002\n\034PB_CS_C_LogonOtherPlatformEx\022\021\n\t" | |||||
"wModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022" | |||||
"\024\n\014cbDeviceType\030\003 \001(\r\022\020\n\010cbGender\030\004 \001(\r\022" | |||||
"\024\n\014cbPlatformID\030\005 \001(\r\022\021\n\tszUserUin\030\006 \001(\t" | |||||
"\022\022\n\nszNickName\030\007 \001(\t\022\026\n\016szCompellation\030\010" | |||||
" \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025\n\rszMobilePho" | |||||
"ne\030\n \001(\t\022\021\n\tszHeadUrl\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t" | |||||
"\n\001y\030\r \001(\022\022\023\n\013isSimulator\030\016 \001(\r\022\023\n\013networ" | |||||
"kType\030\017 \001(\r\022\021\n\tdianliang\030\020 \001(\r\")\n\024PB_CS_" | |||||
"S_UserServerID\022\021\n\twServerID\030\001 \001(\r\"\221\003\n\025PB" | |||||
"_CS_S_tagGameServer\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007" | |||||
"wNodeID\030\002 \001(\r\022\017\n\007wSortID\030\003 \001(\r\022\021\n\twServe" | |||||
"rID\030\004 \001(\r\022\023\n\013wServerKind\030\005 \001(\r\022\023\n\013wServe" | |||||
"rType\030\006 \001(\r\022\023\n\013wServerPort\030\007 \001(\r\022\022\n\nlCel" | |||||
"lScore\030\010 \001(\022\022\023\n\013lEnterScore\030\t \001(\022\022\024\n\014dwS" | |||||
"erverRule\030\n \001(\022\022\025\n\rdwOnLineCount\030\013 \001(\r\022\027" | |||||
"\n\017wTableFullCount\030\014 \001(\r\022\031\n\021wTableOnlineC" | |||||
"ount\030\r \001(\r\022\023\n\013dwFullCount\030\016 \001(\r\022\024\n\014szSer" | |||||
"verAddr\030\017 \001(\t\022\024\n\014szServerName\030\020 \001(\t\022\022\n\nd" | |||||
"wLiveTime\030\021 \001(\022\022\024\n\014wServerLevel\030\022 \001(\rb\006p" | |||||
"roto3" | |||||
======= | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n&Source/MessageDef/Pb_LogonServer.proto" | |||||
"\022\013LogonServer\"\274\001\n\025PB_CS_C_LogonAccounts\022" | |||||
"\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001" | |||||
"(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\022\n\nbLogonType\030\004" | |||||
" \001(\r\022\022\n\nszAccounts\030\005 \001(\t\022\022\n\nszPassword\030\006" | |||||
" \001(\t\022\023\n\013szMachineID\030\007 \001(\t\022\021\n\tszUserUin\030\010" | |||||
" \001(\t\"\304\002\n\024PB_CS_S_LogonSuccess\022\022\n\ndwCusto" | |||||
"mID\030\001 \001(\r\022\020\n\010dwUserID\030\002 \001(\r\022\020\n\010dwGameID\030" | |||||
"\003 \001(\r\022\024\n\014dwExperience\030\004 \001(\r\022\024\n\014dwLoveLin" | |||||
"ess\030\005 \001(\r\022\022\n\nlUserScore\030\006 \001(\021\022\022\n\nlUserIn" | |||||
"got\030\007 \001(\021\022\023\n\013lUserInsure\030\010 \001(\021\022\022\n\ndUserB" | |||||
"eans\030\t \001(\021\022\017\n\007wFaceID\030\n \001(\r\022\020\n\010cbGender\030" | |||||
"\013 \001(\r\022\027\n\017cbInsureEnabled\030\014 \001(\r\022\022\n\nszNick" | |||||
"Name\030\r \001(\t\022\025\n\rszDynamicPass\030\016 \001(\t\022\020\n\010Bin" | |||||
"gDing\030\017 \001(\r\"E\n\024PB_CS_S_LogonFailure\022\023\n\013l" | |||||
"ResultCode\030\001 \001(\022\022\030\n\020szDescribeString\030\002 \001" | |||||
"(\t\"@\n\033PB_CS_C_LogonCheckVerifCode\022\017\n\007bRe" | |||||
"sult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\"Z\n\033PB_CS_S_" | |||||
"LogonCheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010" | |||||
"PhoneNum\030\002 \001(\t\022\030\n\020strErrorDescribe\030\003 \001(\t" | |||||
"\"\347\001\n\030PB_CS_C_RegisterAccounts\022\021\n\twModule" | |||||
"ID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDe" | |||||
"viceType\030\003 \001(\r\022\023\n\013szLogonPass\030\004 \001(\t\022\017\n\007w" | |||||
"FaceID\030\005 \001(\r\022\020\n\010cbGender\030\006 \001(\r\022\022\n\nszAcco" | |||||
"unts\030\007 \001(\t\022\022\n\nszNickName\030\010 \001(\t\022\023\n\013szMach" | |||||
"ineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\"\330\002\n\034P" | |||||
"B_CS_C_LogonOtherPlatformEx\022\021\n\twModuleID" | |||||
"\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDevi" | |||||
"ceType\030\003 \001(\r\022\020\n\010cbGender\030\004 \001(\r\022\024\n\014cbPlat" | |||||
"formID\030\005 \001(\r\022\021\n\tszUserUin\030\006 \001(\t\022\022\n\nszNic" | |||||
"kName\030\007 \001(\t\022\026\n\016szCompellation\030\010 \001(\t\022\023\n\013s" | |||||
"zMachineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\022" | |||||
"\021\n\tszHeadUrl\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022" | |||||
"\022\023\n\013isSimulator\030\016 \001(\r\022\023\n\013networkType\030\017 \001" | |||||
"(\r\022\021\n\tdianliang\030\020 \001(\r\")\n\024PB_CS_S_UserSer" | |||||
"verID\022\021\n\twServerID\030\001 \001(\r\"\221\003\n\025PB_CS_S_tag" | |||||
"GameServer\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007wNodeID\030\002" | |||||
" \001(\r\022\017\n\007wSortID\030\003 \001(\r\022\021\n\twServerID\030\004 \001(\r" | |||||
"\022\023\n\013wServerKind\030\005 \001(\r\022\023\n\013wServerType\030\006 \001" | |||||
"(\r\022\023\n\013wServerPort\030\007 \001(\r\022\022\n\nlCellScore\030\010 " | |||||
"\001(\022\022\023\n\013lEnterScore\030\t \001(\022\022\024\n\014dwServerRule" | |||||
"\030\n \001(\022\022\025\n\rdwOnLineCount\030\013 \001(\r\022\027\n\017wTableF" | |||||
"ullCount\030\014 \001(\r\022\031\n\021wTableOnlineCount\030\r \001(" | |||||
"\r\022\023\n\013dwFullCount\030\016 \001(\r\022\024\n\014szServerAddr\030\017" | |||||
" \001(\t\022\024\n\014szServerName\030\020 \001(\t\022\022\n\ndwLiveTime" | |||||
"\030\021 \001(\022\022\024\n\014wServerLevel\030\022 \001(\rb\006proto3" | |||||
>>>>>>> .r273 | |||||
"D\030\007 \001(\t\022\021\n\tszUserUin\030\010 \001(\t\"\304\002\n\024PB_CS_S_L" | |||||
"ogonSuccess\022\022\n\ndwCustomID\030\001 \001(\r\022\020\n\010dwUse" | |||||
"rID\030\002 \001(\r\022\020\n\010dwGameID\030\003 \001(\r\022\024\n\014dwExperie" | |||||
"nce\030\004 \001(\r\022\024\n\014dwLoveLiness\030\005 \001(\r\022\022\n\nlUser" | |||||
"Score\030\006 \001(\021\022\022\n\nlUserIngot\030\007 \001(\021\022\023\n\013lUser" | |||||
"Insure\030\010 \001(\021\022\022\n\ndUserBeans\030\t \001(\021\022\017\n\007wFac" | |||||
"eID\030\n \001(\r\022\020\n\010cbGender\030\013 \001(\r\022\027\n\017cbInsureE" | |||||
"nabled\030\014 \001(\r\022\022\n\nszNickName\030\r \001(\t\022\025\n\rszDy" | |||||
"namicPass\030\016 \001(\t\022\020\n\010BingDing\030\017 \001(\r\"E\n\024PB_" | |||||
"CS_S_LogonFailure\022\023\n\013lResultCode\030\001 \001(\022\022\030" | |||||
"\n\020szDescribeString\030\002 \001(\t\"@\n\033PB_CS_C_Logo" | |||||
"nCheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010Phon" | |||||
"eNum\030\002 \001(\t\"Z\n\033PB_CS_S_LogonCheckVerifCod" | |||||
"e\022\017\n\007bResult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\022\030\n\020" | |||||
"strErrorDescribe\030\003 \001(\t\"\347\001\n\030PB_CS_C_Regis" | |||||
"terAccounts\022\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlaz" | |||||
"aVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\023\n\013" | |||||
"szLogonPass\030\004 \001(\t\022\017\n\007wFaceID\030\005 \001(\r\022\020\n\010cb" | |||||
"Gender\030\006 \001(\r\022\022\n\nszAccounts\030\007 \001(\t\022\022\n\nszNi" | |||||
"ckName\030\010 \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025\n\rszM" | |||||
"obilePhone\030\n \001(\t\"\330\002\n\034PB_CS_C_LogonOtherP" | |||||
"latformEx\022\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaV" | |||||
"ersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\020\n\010cb" | |||||
"Gender\030\004 \001(\r\022\024\n\014cbPlatformID\030\005 \001(\r\022\021\n\tsz" | |||||
"UserUin\030\006 \001(\t\022\022\n\nszNickName\030\007 \001(\t\022\026\n\016szC" | |||||
"ompellation\030\010 \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025" | |||||
"\n\rszMobilePhone\030\n \001(\t\022\021\n\tszHeadUrl\030\013 \001(\t" | |||||
"\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022\022\023\n\013isSimulator\030\016 " | |||||
"\001(\r\022\023\n\013networkType\030\017 \001(\r\022\021\n\tdianliang\030\020 " | |||||
"\001(\r\")\n\024PB_CS_S_UserServerID\022\021\n\twServerID" | |||||
"\030\001 \001(\r\"\221\003\n\025PB_CS_S_tagGameServer\022\017\n\007wKin" | |||||
"dID\030\001 \001(\r\022\017\n\007wNodeID\030\002 \001(\r\022\017\n\007wSortID\030\003 " | |||||
"\001(\r\022\021\n\twServerID\030\004 \001(\r\022\023\n\013wServerKind\030\005 " | |||||
"\001(\r\022\023\n\013wServerType\030\006 \001(\r\022\023\n\013wServerPort\030" | |||||
"\007 \001(\r\022\022\n\nlCellScore\030\010 \001(\022\022\023\n\013lEnterScore" | |||||
"\030\t \001(\022\022\024\n\014dwServerRule\030\n \001(\022\022\025\n\rdwOnLine" | |||||
"Count\030\013 \001(\r\022\027\n\017wTableFullCount\030\014 \001(\r\022\031\n\021" | |||||
"wTableOnlineCount\030\r \001(\r\022\023\n\013dwFullCount\030\016" | |||||
" \001(\r\022\024\n\014szServerAddr\030\017 \001(\t\022\024\n\014szServerNa" | |||||
"me\030\020 \001(\t\022\022\n\ndwLiveTime\030\021 \001(\022\022\024\n\014wServerL" | |||||
"evel\030\022 \001(\rb\006proto3" | |||||
; | ; | ||||
static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fLogonServer_2eproto_deps[1] = { | static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fLogonServer_2eproto_deps[1] = { | ||||
}; | }; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fLogonServer_2eproto_sccs[8] = { | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fLogonServer_2eproto_sccs[9] = { | |||||
&scc_info_PB_CS_C_LogonAccounts_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_C_LogonAccounts_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_C_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_C_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_C_LogonOtherPlatformEx_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_C_LogonOtherPlatformEx_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_S_LogonSuccess_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_S_LogonSuccess_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_S_UserServerID_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_S_UserServerID_Pb_5fLogonServer_2eproto.base, | ||||
&scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto.base, | &scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto.base, | ||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs[8] = { | |||||
&scc_info_PB_CS_C_LogonAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_LogonOtherPlatformEx_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_RegisterAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonSuccess_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_UserServerID_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_tagGameServer_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs[9] = { | |||||
&scc_info_PB_CS_C_LogonAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_LogonOtherPlatformEx_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_C_RegisterAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_LogonSuccess_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_UserServerID_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
&scc_info_PB_CS_S_tagGameServer_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, | |||||
>>>>>>> .r273 | |||||
}; | }; | ||||
<<<<<<< .mine | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fLogonServer_2eproto_once; | static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fLogonServer_2eproto_once; | ||||
static bool descriptor_table_Pb_5fLogonServer_2eproto_initialized = false; | static bool descriptor_table_Pb_5fLogonServer_2eproto_initialized = false; | ||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fLogonServer_2eproto = { | const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fLogonServer_2eproto = { | ||||
&descriptor_table_Pb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Pb_5fLogonServer_2eproto, "Pb_LogonServer.proto", 1707, | |||||
&descriptor_table_Pb_5fLogonServer_2eproto_once, descriptor_table_Pb_5fLogonServer_2eproto_sccs, descriptor_table_Pb_5fLogonServer_2eproto_deps, 8, 0, | |||||
&descriptor_table_Pb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Pb_5fLogonServer_2eproto, "Pb_LogonServer.proto", 1818, | |||||
&descriptor_table_Pb_5fLogonServer_2eproto_once, descriptor_table_Pb_5fLogonServer_2eproto_sccs, descriptor_table_Pb_5fLogonServer_2eproto_deps, 9, 0, | |||||
schemas, file_default_instances, TableStruct_Pb_5fLogonServer_2eproto::offsets, | schemas, file_default_instances, TableStruct_Pb_5fLogonServer_2eproto::offsets, | ||||
file_level_metadata_Pb_5fLogonServer_2eproto, 8, file_level_enum_descriptors_Pb_5fLogonServer_2eproto, file_level_service_descriptors_Pb_5fLogonServer_2eproto, | |||||
||||||| .r248 | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once; | |||||
static bool descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized = false; | |||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = { | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, "Source/MessageDef/Pb_LogonServer.proto", 1725, | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_deps, 8, 0, | |||||
schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto::offsets, | |||||
file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, 8, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, | |||||
======= | |||||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once; | |||||
static bool descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized = false; | |||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = { | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, "Source/MessageDef/Pb_LogonServer.proto", 1836, | |||||
&descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_deps, 9, 0, | |||||
schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto::offsets, | |||||
file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, 9, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, | |||||
>>>>>>> .r273 | |||||
file_level_metadata_Pb_5fLogonServer_2eproto, 9, file_level_enum_descriptors_Pb_5fLogonServer_2eproto, file_level_service_descriptors_Pb_5fLogonServer_2eproto, | |||||
}; | }; | ||||
// Force running AddDescriptors() at dynamic initialization time. | // Force running AddDescriptors() at dynamic initialization time. | ||||
@@ -1997,7 +1848,7 @@ PB_CS_S_LogonCheckVerifCode::PB_CS_S_LogonCheckVerifCode(const PB_CS_S_LogonChec | |||||
} | } | ||||
void PB_CS_S_LogonCheckVerifCode::SharedCtor() { | void PB_CS_S_LogonCheckVerifCode::SharedCtor() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base); | |||||
phonenum_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | phonenum_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
strerrordescribe_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | strerrordescribe_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); | ||||
bresult_ = 0u; | bresult_ = 0u; | ||||
@@ -2017,7 +1868,7 @@ void PB_CS_S_LogonCheckVerifCode::SetCachedSize(int size) const { | |||||
_cached_size_.Set(size); | _cached_size_.Set(size); | ||||
} | } | ||||
const PB_CS_S_LogonCheckVerifCode& PB_CS_S_LogonCheckVerifCode::default_instance() { | const PB_CS_S_LogonCheckVerifCode& PB_CS_S_LogonCheckVerifCode::default_instance() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base); | |||||
::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base); | |||||
return *internal_default_instance(); | return *internal_default_instance(); | ||||
} | } | ||||
@@ -1014,8 +1014,8 @@ class PB_CS_S_LogonCheckVerifCode : | |||||
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; | ||||
private: | private: | ||||
static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { | ||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto); | |||||
return ::descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fLogonServer_2eproto); | |||||
return ::descriptor_table_Pb_5fLogonServer_2eproto.file_level_metadata[kIndexInFileMessages]; | |||||
} | } | ||||
public: | public: | ||||
@@ -1079,7 +1079,7 @@ class PB_CS_S_LogonCheckVerifCode : | |||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr strerrordescribe_; | ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr strerrordescribe_; | ||||
::PROTOBUF_NAMESPACE_ID::uint32 bresult_; | ::PROTOBUF_NAMESPACE_ID::uint32 bresult_; | ||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; | ||||
friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto; | |||||
friend struct ::TableStruct_Pb_5fLogonServer_2eproto; | |||||
}; | }; | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -162,7 +162,6 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = | |||||
reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::RecordPacket::_PB_CS_S_ReplayRecordResp_default_instance_), | reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::RecordPacket::_PB_CS_S_ReplayRecordResp_default_instance_), | ||||
}; | }; | ||||
<<<<<<< .mine | |||||
const char descriptor_table_protodef_Pb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | const char descriptor_table_protodef_Pb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | ||||
"\n\025Pb_RecordPacket.proto\022\014RecordPacket\"]\n" | "\n\025Pb_RecordPacket.proto\022\014RecordPacket\"]\n" | ||||
"\023pb_GameRecordPacket\022\020\n\010wChairID\030\001 \001(\r\022\022" | "\023pb_GameRecordPacket\022\020\n\010wChairID\030\001 \001(\r\022\022" | ||||
@@ -183,51 +182,6 @@ const char descriptor_table_protodef_Pb_5fRecordPacket_2eproto[] PROTOBUF_SECTIO | |||||
"_chairList\030\007 \003(\0132\034.RecordPacket.pb_Chair" | "_chairList\030\007 \003(\0132\034.RecordPacket.pb_Chair" | ||||
"Record\0228\n\rpRecordPacket\030\010 \003(\0132!.RecordPa" | "Record\0228\n\rpRecordPacket\030\010 \003(\0132!.RecordPa" | ||||
"cket.pb_GameRecordPacketb\006proto3" | "cket.pb_GameRecordPacketb\006proto3" | ||||
||||||| .r248 | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n\'Source/MessageDef/Pb_RecordPacket.prot" | |||||
"o\022\014RecordPacket\"]\n\023pb_GameRecordPacket\022\020" | |||||
"\n\010wChairID\030\001 \001(\r\022\022\n\nwMainCmdID\030\002 \001(\r\022\021\n\t" | |||||
"wSubCmdID\030\003 \001(\r\022\r\n\005pData\030\004 \001(\t\"\201\002\n\rpb_Ga" | |||||
"meConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\020\n\010wDiScore" | |||||
"\030\002 \001(\r\022\017\n\007wFanFei\030\003 \001(\r\022\020\n\010wIpLimit\030\004 \001(" | |||||
"\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\016\n\006RoomId\030\006 \001(" | |||||
"\r\022\017\n\007IsOwner\030\007 \001(\r\022\025\n\rwHadPlayCount\030\010 \001(" | |||||
"\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017\n\007bDuoLai\030\n " | |||||
"\001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tmp1\030\014 \001(\r\022\014\n\004" | |||||
"tmp2\030\r \001(\r\"W\n\016pb_ChairRecord\022\020\n\010wChairId" | |||||
"\030\001 \001(\r\022\020\n\010dwUserId\030\002 \001(\r\022\020\n\010userName\030\003 \001" | |||||
"(\t\022\017\n\007headUrl\030\004 \001(\t\"\204\002\n\030PB_CS_S_ReplayRe" | |||||
"cordResp\022\016\n\006m_UUID\030\001 \001(\r\022\023\n\013m_startTime\030" | |||||
"\003 \001(\r\022\021\n\tm_endTime\030\004 \001(\r\022\020\n\010m_UserId\030\005 \001" | |||||
"(\r\0221\n\014m_gameconfig\030\006 \001(\0132\033.RecordPacket." | |||||
"pb_GameConfig\0221\n\013m_chairList\030\007 \003(\0132\034.Rec" | |||||
"ordPacket.pb_ChairRecord\0228\n\rpRecordPacke" | |||||
"t\030\010 \003(\0132!.RecordPacket.pb_GameRecordPack" | |||||
"etb\006proto3" | |||||
======= | |||||
const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||||
"\n\'Source/MessageDef/Pb_RecordPacket.prot" | |||||
"o\022\014RecordPacket\"]\n\023pb_GameRecordPacket\022\020" | |||||
"\n\010wChairID\030\001 \001(\r\022\022\n\nwMainCmdID\030\002 \001(\r\022\021\n\t" | |||||
"wSubCmdID\030\003 \001(\r\022\r\n\005pData\030\004 \001(\014\"\201\002\n\rpb_Ga" | |||||
"meConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\020\n\010wDiScore" | |||||
"\030\002 \001(\r\022\017\n\007wFanFei\030\003 \001(\r\022\020\n\010wIpLimit\030\004 \001(" | |||||
"\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\016\n\006RoomId\030\006 \001(" | |||||
"\r\022\017\n\007IsOwner\030\007 \001(\r\022\025\n\rwHadPlayCount\030\010 \001(" | |||||
"\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017\n\007bDuoLai\030\n " | |||||
"\001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tmp1\030\014 \001(\r\022\014\n\004" | |||||
"tmp2\030\r \001(\r\"W\n\016pb_ChairRecord\022\020\n\010wChairId" | |||||
"\030\001 \001(\r\022\020\n\010dwUserId\030\002 \001(\r\022\020\n\010userName\030\003 \001" | |||||
"(\t\022\017\n\007headUrl\030\004 \001(\t\"\204\002\n\030PB_CS_S_ReplayRe" | |||||
"cordResp\022\016\n\006m_UUID\030\001 \001(\r\022\023\n\013m_startTime\030" | |||||
"\003 \001(\r\022\021\n\tm_endTime\030\004 \001(\r\022\020\n\010m_UserId\030\005 \001" | |||||
"(\r\0221\n\014m_gameconfig\030\006 \001(\0132\033.RecordPacket." | |||||
"pb_GameConfig\0221\n\013m_chairList\030\007 \003(\0132\034.Rec" | |||||
"ordPacket.pb_ChairRecord\0228\n\rpRecordPacke" | |||||
"t\030\010 \003(\0132!.RecordPacket.pb_GameRecordPack" | |||||
"etb\006proto3" | |||||
>>>>>>> .r273 | |||||
; | ; | ||||
static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fRecordPacket_2eproto_deps[1] = { | static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fRecordPacket_2eproto_deps[1] = { | ||||
}; | }; | ||||
@@ -1,6 +1,6 @@ | |||||
// Generated by the protocol buffer compiler. DO NOT EDIT! | // Generated by the protocol buffer compiler. DO NOT EDIT! | ||||
// source: Pb_Socket.proto | // source: Pb_Socket.proto | ||||
#include "stdafx.h" | |||||
#include "Pb_Socket.pb.h" | #include "Pb_Socket.pb.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
@@ -5,18 +5,10 @@ | |||||
<Configuration>Debug_Unicode</Configuration> | <Configuration>Debug_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Debug|Win32"> | |||||
<Configuration>Debug</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
<ProjectConfiguration Include="Release_Unicode|Win32"> | <ProjectConfiguration Include="Release_Unicode|Win32"> | ||||
<Configuration>Release_Unicode</Configuration> | <Configuration>Release_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|Win32"> | |||||
<Configuration>Release</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
</ItemGroup> | </ItemGroup> | ||||
<PropertyGroup Label="Globals"> | <PropertyGroup Label="Globals"> | ||||
<ProjectGuid>{CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}</ProjectGuid> | <ProjectGuid>{CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}</ProjectGuid> | ||||
@@ -25,13 +17,6 @@ | |||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||||
<ConfigurationType>Application</ConfigurationType> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<CharacterSet>Unicode</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
@@ -39,14 +24,6 @@ | |||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
<UseOfMfc>Dynamic</UseOfMfc> | <UseOfMfc>Dynamic</UseOfMfc> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||||
<ConfigurationType>Application</ConfigurationType> | |||||
<UseDebugLibraries>false</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||||
<CharacterSet>Unicode</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
@@ -58,58 +35,23 @@ | |||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
<ImportGroup Label="ExtensionSettings"> | <ImportGroup Label="ExtensionSettings"> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<LinkIncremental>true</LinkIncremental> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<LinkIncremental>true</LinkIncremental> | <LinkIncremental>true</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
<IncludePath>../../../\Source\SharedControl\create_dump;$(IncludePath)</IncludePath> | <IncludePath>../../../\Source\SharedControl\create_dump;$(IncludePath)</IncludePath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<LinkIncremental>false</LinkIncremental> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<LinkIncremental>false</LinkIncremental> | <LinkIncremental>false</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
<IncludePath>../../../\Source\SharedControl\create_dump;$(IncludePath)</IncludePath> | <IncludePath>../../../\Source\SharedControl\create_dump;$(IncludePath)</IncludePath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ClCompile> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<Optimization>Disabled</Optimization> | |||||
<PreprocessorDefinitions>_USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<ValidateAllParameters>true</ValidateAllParameters> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<PrecompiledHeader>Use</PrecompiledHeader> | <PrecompiledHeader>Use</PrecompiledHeader> | ||||
@@ -139,33 +81,6 @@ | |||||
</Command> | </Command> | ||||
</PostBuildEvent> | </PostBuildEvent> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ClCompile> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<Optimization>MaxSpeed</Optimization> | |||||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | |||||
<OptimizeReferences>true</OptimizeReferences> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<ValidateAllParameters>true</ValidateAllParameters> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
@@ -232,9 +147,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta | |||||
<ClCompile Include="ServiceUnits.cpp" /> | <ClCompile Include="ServiceUnits.cpp" /> | ||||
<ClCompile Include="StatisticalUser.cpp" /> | <ClCompile Include="StatisticalUser.cpp" /> | ||||
<ClCompile Include="stdafx.cpp"> | <ClCompile Include="stdafx.cpp"> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | ||||
</ClCompile> | </ClCompile> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -5,18 +5,10 @@ | |||||
<Configuration>Debug_Unicode</Configuration> | <Configuration>Debug_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Debug|Win32"> | |||||
<Configuration>Debug</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
<ProjectConfiguration Include="Release_Unicode|Win32"> | <ProjectConfiguration Include="Release_Unicode|Win32"> | ||||
<Configuration>Release_Unicode</Configuration> | <Configuration>Release_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|Win32"> | |||||
<Configuration>Release</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
</ItemGroup> | </ItemGroup> | ||||
<PropertyGroup Label="Globals"> | <PropertyGroup Label="Globals"> | ||||
<ProjectGuid>{5266973A-47AE-481C-BD4B-06E5DB08A99B}</ProjectGuid> | <ProjectGuid>{5266973A-47AE-481C-BD4B-06E5DB08A99B}</ProjectGuid> | ||||
@@ -25,13 +17,6 @@ | |||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||||
<ConfigurationType>Application</ConfigurationType> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<CharacterSet>Unicode</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
@@ -39,14 +24,6 @@ | |||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
<UseOfMfc>Dynamic</UseOfMfc> | <UseOfMfc>Dynamic</UseOfMfc> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||||
<ConfigurationType>Application</ConfigurationType> | |||||
<UseDebugLibraries>false</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||||
<CharacterSet>MultiByte</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
@@ -58,61 +35,24 @@ | |||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
<ImportGroup Label="ExtensionSettings"> | <ImportGroup Label="ExtensionSettings"> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<LinkIncremental>true</LinkIncremental> | |||||
<IncludePath>D:\MJ_CODE\后台代码\松滋市一脚癞油\Source\ServerControl\curl-7.32.0\include;$(IncludePath)</IncludePath> | |||||
<LibraryPath>D:\MJ_CODE\后台代码\松滋市一脚癞油\Source\Libs\Debug_Unicode;$(LibraryPath)</LibraryPath> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<LinkIncremental>true</LinkIncremental> | <LinkIncremental>true</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
<IncludePath>../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json;</IncludePath> | <IncludePath>../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json;</IncludePath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<LinkIncremental>false</LinkIncremental> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<LinkIncremental>false</LinkIncremental> | <LinkIncremental>false</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
<IntDir>$(Configuration)\</IntDir> | <IntDir>$(Configuration)\</IntDir> | ||||
<IncludePath>../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json</IncludePath> | <IncludePath>../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json</IncludePath> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ClCompile> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<Optimization>Disabled</Optimization> | |||||
<PreprocessorDefinitions>_USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<ValidateAllParameters>true</ValidateAllParameters> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | <PrecompiledHeader>NotUsing</PrecompiledHeader> | ||||
@@ -145,33 +85,6 @@ | |||||
</Command> | </Command> | ||||
</PostBuildEvent> | </PostBuildEvent> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ClCompile> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<Optimization>MaxSpeed</Optimization> | |||||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | |||||
<OptimizeReferences>true</OptimizeReferences> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<ValidateAllParameters>true</ValidateAllParameters> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
@@ -276,9 +189,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta | |||||
<ClCompile Include="StackWalker.cpp" /> | <ClCompile Include="StackWalker.cpp" /> | ||||
<ClCompile Include="StatisticalUser.cpp" /> | <ClCompile Include="StatisticalUser.cpp" /> | ||||
<ClCompile Include="stdafx.cpp"> | <ClCompile Include="stdafx.cpp"> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="TableFrame.cpp" /> | <ClCompile Include="TableFrame.cpp" /> | ||||
@@ -5,18 +5,10 @@ | |||||
<Configuration>Debug_Unicode</Configuration> | <Configuration>Debug_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Debug|Win32"> | |||||
<Configuration>Debug</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
<ProjectConfiguration Include="Release_Unicode|Win32"> | <ProjectConfiguration Include="Release_Unicode|Win32"> | ||||
<Configuration>Release_Unicode</Configuration> | <Configuration>Release_Unicode</Configuration> | ||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|Win32"> | |||||
<Configuration>Release</Configuration> | |||||
<Platform>Win32</Platform> | |||||
</ProjectConfiguration> | |||||
</ItemGroup> | </ItemGroup> | ||||
<PropertyGroup Label="Globals"> | <PropertyGroup Label="Globals"> | ||||
<ProjectGuid>{51FD2060-F4F9-4982-8474-473541D4FCF8}</ProjectGuid> | <ProjectGuid>{51FD2060-F4F9-4982-8474-473541D4FCF8}</ProjectGuid> | ||||
@@ -25,13 +17,6 @@ | |||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<CharacterSet>Unicode</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
@@ -39,14 +24,6 @@ | |||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
<UseOfMfc>Dynamic</UseOfMfc> | <UseOfMfc>Dynamic</UseOfMfc> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||||
<UseDebugLibraries>false</UseDebugLibraries> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||||
<CharacterSet>Unicode</CharacterSet> | |||||
<UseOfMfc>Dynamic</UseOfMfc> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | ||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
@@ -58,57 +35,22 @@ | |||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
<ImportGroup Label="ExtensionSettings"> | <ImportGroup Label="ExtensionSettings"> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||||
</ImportGroup> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="PropertySheets"> | ||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<LinkIncremental>true</LinkIncremental> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<LinkIncremental>true</LinkIncremental> | <LinkIncremental>true</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
<TargetName>$(ProjectName)D</TargetName> | <TargetName>$(ProjectName)D</TargetName> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<LinkIncremental>false</LinkIncremental> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<LinkIncremental>false</LinkIncremental> | <LinkIncremental>false</LinkIncremental> | ||||
<OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)Bin\$(Configuration)\</OutDir> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ClCompile> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<Optimization>Disabled</Optimization> | |||||
<PreprocessorDefinitions>_USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;_AFXEXT;GAME_SERVICE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
<ModuleDefinitionFile>.\GameService.def</ModuleDefinitionFile> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | <PrecompiledHeader>NotUsing</PrecompiledHeader> | ||||
@@ -139,33 +81,6 @@ | |||||
</Command> | </Command> | ||||
</PostBuildEvent> | </PostBuildEvent> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ClCompile> | |||||
<WarningLevel>Level3</WarningLevel> | |||||
<PrecompiledHeader>Use</PrecompiledHeader> | |||||
<Optimization>MaxSpeed</Optimization> | |||||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_AFXEXT;GAME_SERVICE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<SDLCheck>true</SDLCheck> | |||||
</ClCompile> | |||||
<Link> | |||||
<SubSystem>Windows</SubSystem> | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | |||||
<OptimizeReferences>true</OptimizeReferences> | |||||
<ModuleDefinitionFile>.\GameService.def</ModuleDefinitionFile> | |||||
</Link> | |||||
<Midl> | |||||
<MkTypLibCompatible>false</MkTypLibCompatible> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
</Midl> | |||||
<ResourceCompile> | |||||
<Culture>0x0804</Culture> | |||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||||
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||||
</ResourceCompile> | |||||
</ItemDefinitionGroup> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | ||||
<ClCompile> | <ClCompile> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
@@ -216,9 +131,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta | |||||
<ClCompile Include="GameService.cpp" /> | <ClCompile Include="GameService.cpp" /> | ||||
<ClCompile Include="ServerUserManager.cpp" /> | <ClCompile Include="ServerUserManager.cpp" /> | ||||
<ClCompile Include="stdafx.cpp"> | <ClCompile Include="stdafx.cpp"> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="UserTaskManager.cpp" /> | <ClCompile Include="UserTaskManager.cpp" /> | ||||
@@ -1,12 +1,12 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
<ItemGroup Label="ProjectConfigurations"> | <ItemGroup Label="ProjectConfigurations"> | ||||
<ProjectConfiguration Include="Debug|Win32"> | |||||
<Configuration>Debug</Configuration> | |||||
<ProjectConfiguration Include="Debug_Unicode|Win32"> | |||||
<Configuration>Debug_Unicode</Configuration> | |||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|Win32"> | |||||
<Configuration>Release</Configuration> | |||||
<ProjectConfiguration Include="Release_Unicode|Win32"> | |||||
<Configuration>Release_Unicode</Configuration> | |||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -17,13 +17,13 @@ | |||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'" Label="Configuration"> | |||||
<ConfigurationType>StaticLibrary</ConfigurationType> | <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
<PlatformToolset>v142</PlatformToolset> | <PlatformToolset>v142</PlatformToolset> | ||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'" Label="Configuration"> | |||||
<ConfigurationType>StaticLibrary</ConfigurationType> | <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
<PlatformToolset>v142</PlatformToolset> | <PlatformToolset>v142</PlatformToolset> | ||||
@@ -33,21 +33,21 @@ | |||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
<ImportGroup Label="ExtensionSettings"> | <ImportGroup Label="ExtensionSettings"> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<LinkIncremental>true</LinkIncremental> | <LinkIncremental>true</LinkIncremental> | ||||
<OutDir>../../../\Source\Libs\Debug_Unicode</OutDir> | <OutDir>../../../\Source\Libs\Debug_Unicode</OutDir> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
<LinkIncremental>false</LinkIncremental> | <LinkIncremental>false</LinkIncremental> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<ClCompile> | <ClCompile> | ||||
<PrecompiledHeader>Use</PrecompiledHeader> | <PrecompiledHeader>Use</PrecompiledHeader> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
@@ -60,7 +60,7 @@ | |||||
<GenerateDebugInformation>true</GenerateDebugInformation> | <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
</Link> | </Link> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
<ClCompile> | <ClCompile> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
<PrecompiledHeader>Use</PrecompiledHeader> | <PrecompiledHeader>Use</PrecompiledHeader> | ||||
@@ -95,11 +95,11 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ClCompile Include="dllmain.cpp"> | <ClCompile Include="dllmain.cpp"> | ||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
</PrecompiledHeader> | </PrecompiledHeader> | ||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
</PrecompiledHeader> | </PrecompiledHeader> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="Json.cpp" /> | <ClCompile Include="Json.cpp" /> | ||||
@@ -107,8 +107,8 @@ | |||||
<ClCompile Include="json_value.cpp" /> | <ClCompile Include="json_value.cpp" /> | ||||
<ClCompile Include="json_writer.cpp" /> | <ClCompile Include="json_writer.cpp" /> | ||||
<ClCompile Include="stdafx.cpp"> | <ClCompile Include="stdafx.cpp"> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'">Create</PrecompiledHeader> | |||||
</ClCompile> | </ClCompile> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -1,4 +1,4 @@ | |||||
#include "StdAfx.h" | |||||
#include "stdafx.h" | |||||
#include "QueueService.h" | #include "QueueService.h" | ||||
////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////// | ||||
@@ -1,20 +1,20 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
<ItemGroup Label="ProjectConfigurations"> | <ItemGroup Label="ProjectConfigurations"> | ||||
<ProjectConfiguration Include="Debug|Win32"> | |||||
<Configuration>Debug</Configuration> | |||||
<ProjectConfiguration Include="Debug_Unicode|Win32"> | |||||
<Configuration>Debug_Unicode</Configuration> | |||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Debug|x64"> | |||||
<Configuration>Debug</Configuration> | |||||
<ProjectConfiguration Include="Debug_Unicode|x64"> | |||||
<Configuration>Debug_Unicode</Configuration> | |||||
<Platform>x64</Platform> | <Platform>x64</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|Win32"> | |||||
<Configuration>Release</Configuration> | |||||
<ProjectConfiguration Include="Release_Unicode|Win32"> | |||||
<Configuration>Release_Unicode</Configuration> | |||||
<Platform>Win32</Platform> | <Platform>Win32</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
<ProjectConfiguration Include="Release|x64"> | |||||
<Configuration>Release</Configuration> | |||||
<ProjectConfiguration Include="Release_Unicode|x64"> | |||||
<Configuration>Release_Unicode</Configuration> | |||||
<Platform>x64</Platform> | <Platform>x64</Platform> | ||||
</ProjectConfiguration> | </ProjectConfiguration> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -22,27 +22,28 @@ | |||||
<ProjectGuid>{A24A269E-D5C3-4D96-B5D3-A254D91F617D}</ProjectGuid> | <ProjectGuid>{A24A269E-D5C3-4D96-B5D3-A254D91F617D}</ProjectGuid> | ||||
<Keyword>Win32Proj</Keyword> | <Keyword>Win32Proj</Keyword> | ||||
<RootNamespace>create_dump</RootNamespace> | <RootNamespace>create_dump</RootNamespace> | ||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'" Label="Configuration"> | |||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
<PlatformToolset>v120</PlatformToolset> | <PlatformToolset>v120</PlatformToolset> | ||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'" Label="Configuration"> | |||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
<PlatformToolset>v120</PlatformToolset> | <PlatformToolset>v120</PlatformToolset> | ||||
<WholeProgramOptimization>true</WholeProgramOptimization> | <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<PlatformToolset>v142</PlatformToolset> | <PlatformToolset>v142</PlatformToolset> | ||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
<PlatformToolset>v142</PlatformToolset> | <PlatformToolset>v142</PlatformToolset> | ||||
<ConfigurationType>DynamicLibrary</ConfigurationType> | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
<CharacterSet>Unicode</CharacterSet> | <CharacterSet>Unicode</CharacterSet> | ||||
@@ -50,28 +51,29 @@ | |||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
<ImportGroup Label="ExtensionSettings"> | <ImportGroup Label="ExtensionSettings"> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'" Label="PropertySheets"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> | |||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'" Label="PropertySheets"> | |||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
<PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'"> | |||||
<LinkIncremental>true</LinkIncremental> | <LinkIncremental>true</LinkIncremental> | ||||
<OutDir>..\BIN\Client\X64\Debug\</OutDir> | <OutDir>..\BIN\Client\X64\Debug\</OutDir> | ||||
<IntDir>..\Obj\Client\X64\Dump\Debug\</IntDir> | <IntDir>..\Obj\Client\X64\Dump\Debug\</IntDir> | ||||
<TargetName>$(ProjectName)</TargetName> | <TargetName>$(ProjectName)</TargetName> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'"> | |||||
<LinkIncremental>false</LinkIncremental> | <LinkIncremental>false</LinkIncremental> | ||||
<OutDir>..\BIN\Client\X64\Release\</OutDir> | <OutDir>..\BIN\Client\X64\Release\</OutDir> | ||||
<IntDir>..\obj\Client\X64\dump\Release\</IntDir> | <IntDir>..\obj\Client\X64\dump\Release\</IntDir> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<TargetExt>.dll</TargetExt> | <TargetExt>.dll</TargetExt> | ||||
<TargetName>$(ProjectName)D</TargetName> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'"> | |||||
<ClCompile> | <ClCompile> | ||||
<PrecompiledHeader>Use</PrecompiledHeader> | <PrecompiledHeader>Use</PrecompiledHeader> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
@@ -92,7 +94,7 @@ del "..\LIB\Server\X64\Debug\create_dump.lib" | |||||
xcopy "..\LIB\Client\X64\Debug\create_dump.lib" "..\LIB\Server\X64\Debug\"</Command> | xcopy "..\LIB\Client\X64\Debug\create_dump.lib" "..\LIB\Server\X64\Debug\"</Command> | ||||
</PostBuildEvent> | </PostBuildEvent> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'"> | |||||
<ClCompile> | <ClCompile> | ||||
<WarningLevel>Level3</WarningLevel> | <WarningLevel>Level3</WarningLevel> | ||||
<PrecompiledHeader>Use</PrecompiledHeader> | <PrecompiledHeader>Use</PrecompiledHeader> | ||||
@@ -116,12 +118,12 @@ del "..\LIB\Server\X64\Release\create_dump.lib" | |||||
xcopy "..\LIB\Client\X64\Release\create_dump.lib" "..\LIB\Server\X64\Release\"</Command> | xcopy "..\LIB\Client\X64\Release\create_dump.lib" "..\LIB\Server\X64\Release\"</Command> | ||||
</PostBuildEvent> | </PostBuildEvent> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|Win32'"> | |||||
<ClCompile> | <ClCompile> | ||||
<PreprocessorDefinitions>CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | <PreprocessorDefinitions>CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
</ClCompile> | </ClCompile> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|Win32'"> | |||||
<ClCompile> | <ClCompile> | ||||
<PreprocessorDefinitions>CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | <PreprocessorDefinitions>CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
</ClCompile> | </ClCompile> | ||||
@@ -137,16 +139,16 @@ xcopy "..\LIB\Client\X64\Release\create_dump.lib" "..\LIB\Server\X64\Release\"</ | |||||
<ItemGroup> | <ItemGroup> | ||||
<ClCompile Include="create_dump.cpp" /> | <ClCompile Include="create_dump.cpp" /> | ||||
<ClCompile Include="dllmain.cpp"> | <ClCompile Include="dllmain.cpp"> | ||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'"> | |||||
</PrecompiledHeader> | </PrecompiledHeader> | ||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'">false</CompileAsManaged> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'"> | |||||
</PrecompiledHeader> | </PrecompiledHeader> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="stdafx.cpp"> | <ClCompile Include="stdafx.cpp"> | ||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug_Unicode|x64'">Create</PrecompiledHeader> | |||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_Unicode|x64'">Create</PrecompiledHeader> | |||||
</ClCompile> | </ClCompile> | ||||
</ItemGroup> | </ItemGroup> | ||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
@@ -0,0 +1,8 @@ | |||||
/hiredis-test | |||||
/examples/hiredis-example* | |||||
/*.o | |||||
/*.so | |||||
/*.dylib | |||||
/*.a | |||||
/*.pc | |||||
*.dSYM |
@@ -0,0 +1,97 @@ | |||||
language: c | |||||
sudo: false | |||||
compiler: | |||||
- gcc | |||||
- clang | |||||
os: | |||||
- linux | |||||
- osx | |||||
branches: | |||||
only: | |||||
- staging | |||||
- trying | |||||
- master | |||||
before_script: | |||||
- if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi | |||||
addons: | |||||
apt: | |||||
packages: | |||||
- libc6-dbg | |||||
- libc6-dev | |||||
- libc6:i386 | |||||
- libc6-dev-i386 | |||||
- libc6-dbg:i386 | |||||
- gcc-multilib | |||||
- g++-multilib | |||||
- valgrind | |||||
env: | |||||
- BITS="32" | |||||
- BITS="64" | |||||
script: | |||||
- EXTRA_CMAKE_OPTS="-DENABLE_EXAMPLES:BOOL=ON -DHIREDIS_SSL:BOOL=ON"; | |||||
if [ "$TRAVIS_OS_NAME" == "osx" ]; then | |||||
if [ "$BITS" == "32" ]; then | |||||
CFLAGS="-m32 -Werror"; | |||||
CXXFLAGS="-m32 -Werror"; | |||||
LDFLAGS="-m32"; | |||||
EXTRA_CMAKE_OPTS=; | |||||
else | |||||
CFLAGS="-Werror"; | |||||
CXXFLAGS="-Werror"; | |||||
fi; | |||||
else | |||||
TEST_PREFIX="valgrind --track-origins=yes --leak-check=full"; | |||||
if [ "$BITS" == "32" ]; then | |||||
CFLAGS="-m32 -Werror"; | |||||
CXXFLAGS="-m32 -Werror"; | |||||
LDFLAGS="-m32"; | |||||
EXTRA_CMAKE_OPTS=; | |||||
else | |||||
CFLAGS="-Werror"; | |||||
CXXFLAGS="-Werror"; | |||||
fi; | |||||
fi; | |||||
export CFLAGS CXXFLAGS LDFLAGS TEST_PREFIX EXTRA_CMAKE_OPTS | |||||
- mkdir build/ && cd build/ | |||||
- cmake .. ${EXTRA_CMAKE_OPTS} | |||||
- make VERBOSE=1 | |||||
- ctest -V | |||||
matrix: | |||||
include: | |||||
# Windows MinGW cross compile on Linux | |||||
- os: linux | |||||
dist: xenial | |||||
compiler: mingw | |||||
addons: | |||||
apt: | |||||
packages: | |||||
- ninja-build | |||||
- gcc-mingw-w64-x86-64 | |||||
- g++-mingw-w64-x86-64 | |||||
script: | |||||
- mkdir build && cd build | |||||
- CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_WITH_INSTALL_RPATH=on | |||||
- ninja -v | |||||
# Windows MSVC 2017 | |||||
- os: windows | |||||
compiler: msvc | |||||
env: | |||||
- MATRIX_EVAL="CC=cl.exe && CXX=cl.exe" | |||||
before_install: | |||||
- eval "${MATRIX_EVAL}" | |||||
install: | |||||
- choco install ninja | |||||
script: | |||||
- mkdir build && cd build | |||||
- cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 && | |||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release && | |||||
ninja -v' | |||||
- ctest -V |
@@ -0,0 +1,199 @@ | |||||
### 1.0.0 (unreleased) | |||||
**BREAKING CHANGES**: | |||||
* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now | |||||
protocol errors. This is consistent with the RESP specification. On 32-bit | |||||
platforms, the upper bound is lowered to `SIZE_MAX`. | |||||
* Change `redisReply.len` to `size_t`, as it denotes the the size of a string | |||||
User code should compare this to `size_t` values as well. If it was used to | |||||
compare to other values, casting might be necessary or can be removed, if | |||||
casting was applied before. | |||||
### 0.x.x (unreleased) | |||||
**BREAKING CHANGES**: | |||||
* Change `redisReply.len` to `size_t`, as it denotes the the size of a string | |||||
User code should compare this to `size_t` values as well. | |||||
If it was used to compare to other values, casting might be necessary or can be removed, if casting was applied before. | |||||
* `redisReplyObjectFunctions.createArray` now takes `size_t` for its length parameter. | |||||
### 0.14.0 (2018-09-25) | |||||
* Make string2ll static to fix conflict with Redis (Tom Lee [c3188b]) | |||||
* Use -dynamiclib instead of -shared for OSX (Ryan Schmidt [a65537]) | |||||
* Use string2ll from Redis w/added tests (Michael Grunder [7bef04, 60f622]) | |||||
* Makefile - OSX compilation fixes (Ryan Schmidt [881fcb, 0e9af8]) | |||||
* Remove redundant NULL checks (Justin Brewer [54acc8, 58e6b8]) | |||||
* Fix bulk and multi-bulk length truncation (Justin Brewer [109197]) | |||||
* Fix SIGSEGV in OpenBSD by checking for NULL before calling freeaddrinfo (Justin Brewer [546d94]) | |||||
* Several POSIX compatibility fixes (Justin Brewer [bbeab8, 49bbaa, d1c1b6]) | |||||
* Makefile - Compatibility fixes (Dimitri Vorobiev [3238cf, 12a9d1]) | |||||
* Makefile - Fix make install on FreeBSD (Zach Shipko [a2ef2b]) | |||||
* Makefile - don't assume $(INSTALL) is cp (Igor Gnatenko [725a96]) | |||||
* Separate side-effect causing function from assert and small cleanup (amallia [b46413, 3c3234]) | |||||
* Don't send negative values to `__redisAsyncCommand` (Frederik Deweerdt [706129]) | |||||
* Fix leak if setsockopt fails (Frederik Deweerdt [e21c9c]) | |||||
* Fix libevent leak (zfz [515228]) | |||||
* Clean up GCC warning (Ichito Nagata [2ec774]) | |||||
* Keep track of errno in `__redisSetErrorFromErrno()` as snprintf may use it (Jin Qing [25cd88]) | |||||
* Solaris compilation fix (Donald Whyte [41b07d]) | |||||
* Reorder linker arguments when building examples (Tustfarm-heart [06eedd]) | |||||
* Keep track of subscriptions in case of rapid subscribe/unsubscribe (Hyungjin Kim [073dc8, be76c5, d46999]) | |||||
* libuv use after free fix (Paul Scott [cbb956]) | |||||
* Properly close socket fd on reconnect attempt (WSL [64d1ec]) | |||||
* Skip valgrind in OSX tests (Jan-Erik Rediger [9deb78]) | |||||
* Various updates for Travis testing OSX (Ted Nyman [fa3774, 16a459, bc0ea5]) | |||||
* Update libevent (Chris Xin [386802]) | |||||
* Change sds.h for building in C++ projects (Ali Volkan ATLI [f5b32e]) | |||||
* Use proper format specifier in redisFormatSdsCommandArgv (Paulino Huerta, Jan-Erik Rediger [360a06, 8655a6]) | |||||
* Better handling of NULL reply in example code (Jan-Erik Rediger [1b8ed3]) | |||||
* Prevent overflow when formatting an error (Jan-Erik Rediger [0335cb]) | |||||
* Compatibility fix for strerror_r (Tom Lee [bb1747]) | |||||
* Properly detect integer parse/overflow errors (Justin Brewer [93421f]) | |||||
* Adds CI for Windows and cygwin fixes (owent, [6c53d6, 6c3e40]) | |||||
* Catch a buffer overflow when formatting the error message | |||||
* Import latest upstream sds. This breaks applications that are linked against the old hiredis v0.13 | |||||
* Fix warnings, when compiled with -Wshadow | |||||
* Make hiredis compile in Cygwin on Windows, now CI-tested | |||||
* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now | |||||
protocol errors. This is consistent with the RESP specification. On 32-bit | |||||
platforms, the upper bound is lowered to `SIZE_MAX`. | |||||
* Remove backwards compatibility macro's | |||||
This removes the following old function aliases, use the new name now: | |||||
| Old | New | | |||||
| --------------------------- | ---------------------- | | |||||
| redisReplyReaderCreate | redisReaderCreate | | |||||
| redisReplyReaderCreate | redisReaderCreate | | |||||
| redisReplyReaderFree | redisReaderFree | | |||||
| redisReplyReaderFeed | redisReaderFeed | | |||||
| redisReplyReaderGetReply | redisReaderGetReply | | |||||
| redisReplyReaderSetPrivdata | redisReaderSetPrivdata | | |||||
| redisReplyReaderGetObject | redisReaderGetObject | | |||||
| redisReplyReaderGetError | redisReaderGetError | | |||||
* The `DEBUG` variable in the Makefile was renamed to `DEBUG_FLAGS` | |||||
Previously it broke some builds for people that had `DEBUG` set to some arbitrary value, | |||||
due to debugging other software. | |||||
By renaming we avoid unintentional name clashes. | |||||
Simply rename `DEBUG` to `DEBUG_FLAGS` in your environment to make it working again. | |||||
### 0.13.3 (2015-09-16) | |||||
* Revert "Clear `REDIS_CONNECTED` flag when connection is closed". | |||||
* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni) | |||||
If the `REDIS_CONNECTED` flag is cleared, | |||||
the async onDisconnect callback function will never be called. | |||||
This causes problems as the disconnect is never reported back to the user. | |||||
### 0.13.2 (2015-08-25) | |||||
* Prevent crash on pending replies in async code (Thanks, @switch-st) | |||||
* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs) | |||||
* Add MacOS X addapter (Thanks, @dizzus) | |||||
* Add Qt adapter (Thanks, Pietro Cerutti) | |||||
* Add Ivykis adapter (Thanks, Gergely Nagy) | |||||
All adapters are provided as is and are only tested where possible. | |||||
### 0.13.1 (2015-05-03) | |||||
This is a bug fix release. | |||||
The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code. | |||||
Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects. | |||||
Other non-C99 code can now use hiredis as usual again. | |||||
Sorry for the inconvenience. | |||||
* Fix memory leak in async reply handling (Salvatore Sanfilippo) | |||||
* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa) | |||||
### 0.13.0 (2015-04-16) | |||||
This release adds a minimal Windows compatibility layer. | |||||
The parser, standalone since v0.12.0, can now be compiled on Windows | |||||
(and thus used in other client libraries as well) | |||||
* Windows compatibility layer for parser code (tzickel) | |||||
* Properly escape data printed to PKGCONF file (Dan Skorupski) | |||||
* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff) | |||||
* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra) | |||||
### 0.12.1 (2015-01-26) | |||||
* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location | |||||
* Fix `make test` as 32 bit build on 64 bit platform | |||||
### 0.12.0 (2015-01-22) | |||||
* Add optional KeepAlive support | |||||
* Try again on EINTR errors | |||||
* Add libuv adapter | |||||
* Add IPv6 support | |||||
* Remove possibility of multiple close on same fd | |||||
* Add ability to bind source address on connect | |||||
* Add redisConnectFd() and redisFreeKeepFd() | |||||
* Fix getaddrinfo() memory leak | |||||
* Free string if it is unused (fixes memory leak) | |||||
* Improve redisAppendCommandArgv performance 2.5x | |||||
* Add support for SO_REUSEADDR | |||||
* Fix redisvFormatCommand format parsing | |||||
* Add GLib 2.0 adapter | |||||
* Refactor reading code into read.c | |||||
* Fix errno error buffers to not clobber errors | |||||
* Generate pkgconf during build | |||||
* Silence _BSD_SOURCE warnings | |||||
* Improve digit counting for multibulk creation | |||||
### 0.11.0 | |||||
* Increase the maximum multi-bulk reply depth to 7. | |||||
* Increase the read buffer size from 2k to 16k. | |||||
* Use poll(2) instead of select(2) to support large fds (>= 1024). | |||||
### 0.10.1 | |||||
* Makefile overhaul. Important to check out if you override one or more | |||||
variables using environment variables or via arguments to the "make" tool. | |||||
* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements | |||||
being created by the default reply object functions. | |||||
* Issue #43: Don't crash in an asynchronous context when Redis returns an error | |||||
reply after the connection has been made (this happens when the maximum | |||||
number of connections is reached). | |||||
### 0.10.0 | |||||
* See commit log. | |||||
@@ -0,0 +1,29 @@ | |||||
Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
All rights reserved. | |||||
Redistribution and use in source and binary forms, with or without | |||||
modification, are permitted provided that the following conditions are met: | |||||
* Redistributions of source code must retain the above copyright notice, | |||||
this list of conditions and the following disclaimer. | |||||
* Redistributions in binary form must reproduce the above copyright notice, | |||||
this list of conditions and the following disclaimer in the documentation | |||||
and/or other materials provided with the distribution. | |||||
* Neither the name of Redis nor the names of its contributors may be used | |||||
to endorse or promote products derived from this software without specific | |||||
prior written permission. | |||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@@ -0,0 +1,274 @@ | |||||
# Hiredis Makefile | |||||
# Copyright (C) 2010-2011 Salvatore Sanfilippo <antirez at gmail dot com> | |||||
# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
# This file is released under the BSD license, see the COPYING file | |||||
OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o alloc.o | |||||
SSL_OBJ=ssl.o | |||||
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib | |||||
ifeq ($(USE_SSL),1) | |||||
EXAMPLES+=hiredis-example-ssl hiredis-example-libevent-ssl | |||||
endif | |||||
TESTS=hiredis-test | |||||
LIBNAME=libhiredis | |||||
SSL_LIBNAME=libhiredis_ssl | |||||
PKGCONFNAME=hiredis.pc | |||||
SSL_PKGCONFNAME=hiredis_ssl.pc | |||||
HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}') | |||||
HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}') | |||||
HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}') | |||||
HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}') | |||||
# Installation related variables and target | |||||
PREFIX?=/usr/local | |||||
INCLUDE_PATH?=include/hiredis | |||||
LIBRARY_PATH?=lib | |||||
PKGCONF_PATH?=pkgconfig | |||||
INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH) | |||||
INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) | |||||
INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH) | |||||
# redis-server configuration used for testing | |||||
REDIS_PORT=56379 | |||||
REDIS_SERVER=redis-server | |||||
define REDIS_TEST_CONFIG | |||||
daemonize yes | |||||
pidfile /tmp/hiredis-test-redis.pid | |||||
port $(REDIS_PORT) | |||||
bind 127.0.0.1 | |||||
unixsocket /tmp/hiredis-test-redis.sock | |||||
endef | |||||
export REDIS_TEST_CONFIG | |||||
# Fallback to gcc when $CC is not in $PATH. | |||||
CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc') | |||||
CXX:=$(shell sh -c 'type $${CXX%% *} >/dev/null 2>/dev/null && echo $(CXX) || echo g++') | |||||
OPTIMIZATION?=-O3 | |||||
WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers | |||||
DEBUG_FLAGS?= -g -ggdb | |||||
REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEBUG_FLAGS) | |||||
REAL_LDFLAGS=$(LDFLAGS) | |||||
DYLIBSUFFIX=so | |||||
STLIBSUFFIX=a | |||||
DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) | |||||
DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) | |||||
DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX) | |||||
SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX) | |||||
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) | |||||
STLIBNAME=$(LIBNAME).$(STLIBSUFFIX) | |||||
SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX) | |||||
STLIB_MAKE_CMD=$(AR) rcs | |||||
# Platform-specific overrides | |||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') | |||||
USE_SSL?=0 | |||||
# This is required for test.c only | |||||
ifeq ($(USE_SSL),1) | |||||
CFLAGS+=-DHIREDIS_TEST_SSL | |||||
endif | |||||
ifeq ($(uname_S),Linux) | |||||
SSL_LDFLAGS=-lssl -lcrypto | |||||
else | |||||
OPENSSL_PREFIX?=/usr/local/opt/openssl | |||||
CFLAGS+=-I$(OPENSSL_PREFIX)/include | |||||
SSL_LDFLAGS+=-L$(OPENSSL_PREFIX)/lib -lssl -lcrypto | |||||
endif | |||||
ifeq ($(uname_S),SunOS) | |||||
REAL_LDFLAGS+= -ldl -lnsl -lsocket | |||||
DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS) | |||||
endif | |||||
ifeq ($(uname_S),Darwin) | |||||
DYLIBSUFFIX=dylib | |||||
DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX) | |||||
DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) | |||||
endif | |||||
all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME) | |||||
ifeq ($(USE_SSL),1) | |||||
all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME) | |||||
endif | |||||
# Deps (use make dep to generate this) | |||||
async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h | |||||
dict.o: dict.c fmacros.h alloc.h dict.h | |||||
hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h | |||||
alloc.o: alloc.c alloc.h | |||||
net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h | |||||
read.o: read.c fmacros.h read.h sds.h win32.h | |||||
sds.o: sds.c sds.h sdsalloc.h | |||||
sockcompat.o: sockcompat.c sockcompat.h | |||||
ssl.o: ssl.c hiredis.h read.h sds.h alloc.h async.h async_private.h | |||||
test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h | |||||
$(DYLIBNAME): $(OBJ) | |||||
$(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS) | |||||
$(STLIBNAME): $(OBJ) | |||||
$(STLIB_MAKE_CMD) $(STLIBNAME) $(OBJ) | |||||
$(SSL_DYLIBNAME): $(SSL_OBJ) | |||||
$(DYLIB_MAKE_CMD) -o $(SSL_DYLIBNAME) $(SSL_OBJ) $(REAL_LDFLAGS) $(SSL_LDFLAGS) | |||||
$(SSL_STLIBNAME): $(SSL_OBJ) | |||||
$(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ) | |||||
dynamic: $(DYLIBNAME) | |||||
static: $(STLIBNAME) | |||||
ifeq ($(USE_SSL),1) | |||||
dynamic: $(SSL_DYLIBNAME) | |||||
static: $(SSL_STLIBNAME) | |||||
endif | |||||
# Binaries: | |||||
hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(REAL_LDFLAGS) | |||||
hiredis-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) | |||||
hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lev $(STLIBNAME) $(REAL_LDFLAGS) | |||||
hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) $(REAL_LDFLAGS) | |||||
hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -livykis $(STLIBNAME) $(REAL_LDFLAGS) | |||||
hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) $(REAL_LDFLAGS) | |||||
hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) | |||||
ifndef AE_DIR | |||||
hiredis-example-ae: | |||||
@echo "Please specify AE_DIR (e.g. <redis repository>/src)" | |||||
@false | |||||
else | |||||
hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME) | |||||
endif | |||||
ifndef LIBUV_DIR | |||||
hiredis-example-libuv: | |||||
@echo "Please specify LIBUV_DIR (e.g. ../libuv/)" | |||||
@false | |||||
else | |||||
hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS) | |||||
endif | |||||
ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),) | |||||
hiredis-example-qt: | |||||
@echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR" | |||||
@false | |||||
else | |||||
hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) | |||||
$(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ | |||||
$(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | |||||
$(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ | |||||
$(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | |||||
$(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore | |||||
endif | |||||
hiredis-example: examples/example.c $(STLIBNAME) | |||||
$(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) | |||||
examples: $(EXAMPLES) | |||||
TEST_LIBS = $(STLIBNAME) | |||||
ifeq ($(USE_SSL),1) | |||||
TEST_LIBS += $(SSL_STLIBNAME) -lssl -lcrypto -lpthread | |||||
endif | |||||
hiredis-test: test.o $(TEST_LIBS) | |||||
hiredis-%: %.o $(STLIBNAME) | |||||
$(CC) $(REAL_CFLAGS) -o $@ $< $(TEST_LIBS) $(REAL_LDFLAGS) | |||||
test: hiredis-test | |||||
./hiredis-test | |||||
check: hiredis-test | |||||
TEST_SSL=$(USE_SSL) ./test.sh | |||||
.c.o: | |||||
$(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $< | |||||
clean: | |||||
rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov | |||||
dep: | |||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c | |||||
INSTALL?= cp -pPR | |||||
$(PKGCONFNAME): hiredis.h | |||||
@echo "Generating $@ for pkgconfig..." | |||||
@echo prefix=$(PREFIX) > $@ | |||||
@echo exec_prefix=\$${prefix} >> $@ | |||||
@echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ | |||||
@echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ | |||||
@echo >> $@ | |||||
@echo Name: hiredis >> $@ | |||||
@echo Description: Minimalistic C client library for Redis. >> $@ | |||||
@echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ | |||||
@echo Libs: -L\$${libdir} -lhiredis >> $@ | |||||
@echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@ | |||||
$(SSL_PKGCONFNAME): hiredis.h | |||||
@echo "Generating $@ for pkgconfig..." | |||||
@echo prefix=$(PREFIX) > $@ | |||||
@echo exec_prefix=\$${prefix} >> $@ | |||||
@echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ | |||||
@echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ | |||||
@echo >> $@ | |||||
@echo Name: hiredis_ssl >> $@ | |||||
@echo Description: SSL Support for hiredis. >> $@ | |||||
@echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ | |||||
@echo Requires: hiredis >> $@ | |||||
@echo Libs: -L\$${libdir} -lhiredis_ssl >> $@ | |||||
@echo Libs.private: -lssl -lcrypto >> $@ | |||||
install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) | |||||
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH) | |||||
$(INSTALL) hiredis.h async.h read.h sds.h alloc.h $(INSTALL_INCLUDE_PATH) | |||||
$(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters | |||||
$(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) | |||||
cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME) | |||||
$(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH) | |||||
mkdir -p $(INSTALL_PKGCONF_PATH) | |||||
$(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH) | |||||
32bit: | |||||
@echo "" | |||||
@echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386" | |||||
@echo "" | |||||
$(MAKE) CFLAGS="-m32" LDFLAGS="-m32" | |||||
32bit-vars: | |||||
$(eval CFLAGS=-m32) | |||||
$(eval LDFLAGS=-m32) | |||||
gprof: | |||||
$(MAKE) CFLAGS="-pg" LDFLAGS="-pg" | |||||
gcov: | |||||
$(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" | |||||
coverage: gcov | |||||
make check | |||||
mkdir -p tmp/lcov | |||||
lcov -d . -c -o tmp/lcov/hiredis.info | |||||
genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info | |||||
noopt: | |||||
$(MAKE) OPTIMIZATION="" | |||||
.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt |
@@ -0,0 +1,470 @@ | |||||
[](https://travis-ci.org/redis/hiredis) | |||||
**This Readme reflects the latest changed in the master branch. See [v0.13.3](https://github.com/redis/hiredis/tree/v0.13.3) for the Readme and documentation for the latest release.** | |||||
# HIREDIS | |||||
Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database. | |||||
It is minimalistic because it just adds minimal support for the protocol, but | |||||
at the same time it uses a high level printf-alike API in order to make it | |||||
much higher level than otherwise suggested by its minimal code base and the | |||||
lack of explicit bindings for every Redis command. | |||||
Apart from supporting sending commands and receiving replies, it comes with | |||||
a reply parser that is decoupled from the I/O layer. It | |||||
is a stream parser designed for easy reusability, which can for instance be used | |||||
in higher level language bindings for efficient reply parsing. | |||||
Hiredis only supports the binary-safe Redis protocol, so you can use it with any | |||||
Redis version >= 1.2.0. | |||||
The library comes with multiple APIs. There is the | |||||
*synchronous API*, the *asynchronous API* and the *reply parsing API*. | |||||
## Upgrading to `1.0.0` | |||||
Version 1.0.0 marks a stable release of hiredis. | |||||
It includes some minor breaking changes, mostly to make the exposed API more uniform and self-explanatory. | |||||
It also bundles the updated `sds` library, to sync up with upstream and Redis. | |||||
For most applications a recompile against the new hiredis should be enough. | |||||
For code changes see the [Changelog](CHANGELOG.md). | |||||
## Upgrading from `<0.9.0` | |||||
Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing | |||||
code using hiredis should not be a big pain. The key thing to keep in mind when | |||||
upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to | |||||
the stateless 0.0.1 that only has a file descriptor to work with. | |||||
## Synchronous API | |||||
To consume the synchronous API, there are only a few function calls that need to be introduced: | |||||
```c | |||||
redisContext *redisConnect(const char *ip, int port); | |||||
void *redisCommand(redisContext *c, const char *format, ...); | |||||
void freeReplyObject(void *reply); | |||||
``` | |||||
### Connecting | |||||
The function `redisConnect` is used to create a so-called `redisContext`. The | |||||
context is where Hiredis holds state for a connection. The `redisContext` | |||||
struct has an integer `err` field that is non-zero when the connection is in | |||||
an error state. The field `errstr` will contain a string with a description of | |||||
the error. More information on errors can be found in the **Errors** section. | |||||
After trying to connect to Redis using `redisConnect` you should | |||||
check the `err` field to see if establishing the connection was successful: | |||||
```c | |||||
redisContext *c = redisConnect("127.0.0.1", 6379); | |||||
if (c == NULL || c->err) { | |||||
if (c) { | |||||
printf("Error: %s\n", c->errstr); | |||||
// handle error | |||||
} else { | |||||
printf("Can't allocate redis context\n"); | |||||
} | |||||
} | |||||
``` | |||||
*Note: A `redisContext` is not thread-safe.* | |||||
### Sending commands | |||||
There are several ways to issue commands to Redis. The first that will be introduced is | |||||
`redisCommand`. This function takes a format similar to printf. In the simplest form, | |||||
it is used like this: | |||||
```c | |||||
reply = redisCommand(context, "SET foo bar"); | |||||
``` | |||||
The specifier `%s` interpolates a string in the command, and uses `strlen` to | |||||
determine the length of the string: | |||||
```c | |||||
reply = redisCommand(context, "SET foo %s", value); | |||||
``` | |||||
When you need to pass binary safe strings in a command, the `%b` specifier can be | |||||
used. Together with a pointer to the string, it requires a `size_t` length argument | |||||
of the string: | |||||
```c | |||||
reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); | |||||
``` | |||||
Internally, Hiredis splits the command in different arguments and will | |||||
convert it to the protocol used to communicate with Redis. | |||||
One or more spaces separates arguments, so you can use the specifiers | |||||
anywhere in an argument: | |||||
```c | |||||
reply = redisCommand(context, "SET key:%s %s", myid, value); | |||||
``` | |||||
### Using replies | |||||
The return value of `redisCommand` holds a reply when the command was | |||||
successfully executed. When an error occurs, the return value is `NULL` and | |||||
the `err` field in the context will be set (see section on **Errors**). | |||||
Once an error is returned the context cannot be reused and you should set up | |||||
a new connection. | |||||
The standard replies that `redisCommand` are of the type `redisReply`. The | |||||
`type` field in the `redisReply` should be used to test what kind of reply | |||||
was received: | |||||
* **`REDIS_REPLY_STATUS`**: | |||||
* The command replied with a status reply. The status string can be accessed using `reply->str`. | |||||
The length of this string can be accessed using `reply->len`. | |||||
* **`REDIS_REPLY_ERROR`**: | |||||
* The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. | |||||
* **`REDIS_REPLY_INTEGER`**: | |||||
* The command replied with an integer. The integer value can be accessed using the | |||||
`reply->integer` field of type `long long`. | |||||
* **`REDIS_REPLY_NIL`**: | |||||
* The command replied with a **nil** object. There is no data to access. | |||||
* **`REDIS_REPLY_STRING`**: | |||||
* A bulk (string) reply. The value of the reply can be accessed using `reply->str`. | |||||
The length of this string can be accessed using `reply->len`. | |||||
* **`REDIS_REPLY_ARRAY`**: | |||||
* A multi bulk reply. The number of elements in the multi bulk reply is stored in | |||||
`reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well | |||||
and can be accessed via `reply->element[..index..]`. | |||||
Redis may reply with nested arrays but this is fully supported. | |||||
Replies should be freed using the `freeReplyObject()` function. | |||||
Note that this function will take care of freeing sub-reply objects | |||||
contained in arrays and nested arrays, so there is no need for the user to | |||||
free the sub replies (it is actually harmful and will corrupt the memory). | |||||
**Important:** the current version of hiredis (0.10.0) frees replies when the | |||||
asynchronous API is used. This means you should not call `freeReplyObject` when | |||||
you use this API. The reply is cleaned up by hiredis _after_ the callback | |||||
returns. This behavior will probably change in future releases, so make sure to | |||||
keep an eye on the changelog when upgrading (see issue #39). | |||||
### Cleaning up | |||||
To disconnect and free the context the following function can be used: | |||||
```c | |||||
void redisFree(redisContext *c); | |||||
``` | |||||
This function immediately closes the socket and then frees the allocations done in | |||||
creating the context. | |||||
### Sending commands (cont'd) | |||||
Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. | |||||
It has the following prototype: | |||||
```c | |||||
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |||||
``` | |||||
It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the | |||||
arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will | |||||
use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments | |||||
need to be binary safe, the entire array of lengths `argvlen` should be provided. | |||||
The return value has the same semantic as `redisCommand`. | |||||
### Pipelining | |||||
To explain how Hiredis supports pipelining in a blocking connection, there needs to be | |||||
understanding of the internal execution flow. | |||||
When any of the functions in the `redisCommand` family is called, Hiredis first formats the | |||||
command according to the Redis protocol. The formatted command is then put in the output buffer | |||||
of the context. This output buffer is dynamic, so it can hold any number of commands. | |||||
After the command is put in the output buffer, `redisGetReply` is called. This function has the | |||||
following two execution paths: | |||||
1. The input buffer is non-empty: | |||||
* Try to parse a single reply from the input buffer and return it | |||||
* If no reply could be parsed, continue at *2* | |||||
2. The input buffer is empty: | |||||
* Write the **entire** output buffer to the socket | |||||
* Read from the socket until a single reply could be parsed | |||||
The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply | |||||
is expected on the socket. To pipeline commands, the only things that needs to be done is | |||||
filling up the output buffer. For this cause, two commands can be used that are identical | |||||
to the `redisCommand` family, apart from not returning a reply: | |||||
```c | |||||
void redisAppendCommand(redisContext *c, const char *format, ...); | |||||
void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |||||
``` | |||||
After calling either function one or more times, `redisGetReply` can be used to receive the | |||||
subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where | |||||
the latter means an error occurred while reading a reply. Just as with the other commands, | |||||
the `err` field in the context can be used to find out what the cause of this error is. | |||||
The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and | |||||
a single call to `read(2)`): | |||||
```c | |||||
redisReply *reply; | |||||
redisAppendCommand(context,"SET foo bar"); | |||||
redisAppendCommand(context,"GET foo"); | |||||
redisGetReply(context,&reply); // reply for SET | |||||
freeReplyObject(reply); | |||||
redisGetReply(context,&reply); // reply for GET | |||||
freeReplyObject(reply); | |||||
``` | |||||
This API can also be used to implement a blocking subscriber: | |||||
```c | |||||
reply = redisCommand(context,"SUBSCRIBE foo"); | |||||
freeReplyObject(reply); | |||||
while(redisGetReply(context,&reply) == REDIS_OK) { | |||||
// consume message | |||||
freeReplyObject(reply); | |||||
} | |||||
``` | |||||
### Errors | |||||
When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is | |||||
returned. The `err` field inside the context will be non-zero and set to one of the | |||||
following constants: | |||||
* **`REDIS_ERR_IO`**: | |||||
There was an I/O error while creating the connection, trying to write | |||||
to the socket or read from the socket. If you included `errno.h` in your | |||||
application, you can use the global `errno` variable to find out what is | |||||
wrong. | |||||
* **`REDIS_ERR_EOF`**: | |||||
The server closed the connection which resulted in an empty read. | |||||
* **`REDIS_ERR_PROTOCOL`**: | |||||
There was an error while parsing the protocol. | |||||
* **`REDIS_ERR_OTHER`**: | |||||
Any other error. Currently, it is only used when a specified hostname to connect | |||||
to cannot be resolved. | |||||
In every case, the `errstr` field in the context will be set to hold a string representation | |||||
of the error. | |||||
## Asynchronous API | |||||
Hiredis comes with an asynchronous API that works easily with any event library. | |||||
Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) | |||||
and [libevent](http://monkey.org/~provos/libevent/). | |||||
### Connecting | |||||
The function `redisAsyncConnect` can be used to establish a non-blocking connection to | |||||
Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field | |||||
should be checked after creation to see if there were errors creating the connection. | |||||
Because the connection that will be created is non-blocking, the kernel is not able to | |||||
instantly return if the specified host and port is able to accept a connection. | |||||
*Note: A `redisAsyncContext` is not thread-safe.* | |||||
```c | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
printf("Error: %s\n", c->errstr); | |||||
// handle error | |||||
} | |||||
``` | |||||
The asynchronous context can hold a disconnect callback function that is called when the | |||||
connection is disconnected (either because of an error or per user request). This function should | |||||
have the following prototype: | |||||
```c | |||||
void(const redisAsyncContext *c, int status); | |||||
``` | |||||
On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the | |||||
user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` | |||||
field in the context can be accessed to find out the cause of the error. | |||||
The context object is always freed after the disconnect callback fired. When a reconnect is needed, | |||||
the disconnect callback is a good point to do so. | |||||
Setting the disconnect callback can only be done once per context. For subsequent calls it will | |||||
return `REDIS_ERR`. The function to set the disconnect callback has the following prototype: | |||||
```c | |||||
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); | |||||
``` | |||||
`ac->data` may be used to pass user data to this callback, the same can be done for redisConnectCallback. | |||||
### Sending commands and their callbacks | |||||
In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. | |||||
Therefore, unlike the synchronous API, there is only a single way to send commands. | |||||
Because commands are sent to Redis asynchronously, issuing a command requires a callback function | |||||
that is called when the reply is received. Reply callbacks should have the following prototype: | |||||
```c | |||||
void(redisAsyncContext *c, void *reply, void *privdata); | |||||
``` | |||||
The `privdata` argument can be used to curry arbitrary data to the callback from the point where | |||||
the command is initially queued for execution. | |||||
The functions that can be used to issue commands in an asynchronous context are: | |||||
```c | |||||
int redisAsyncCommand( | |||||
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, | |||||
const char *format, ...); | |||||
int redisAsyncCommandArgv( | |||||
redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, | |||||
int argc, const char **argv, const size_t *argvlen); | |||||
``` | |||||
Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command | |||||
was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection | |||||
is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is | |||||
returned on calls to the `redisAsyncCommand` family. | |||||
If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback | |||||
for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only | |||||
valid for the duration of the callback. | |||||
All pending callbacks are called with a `NULL` reply when the context encountered an error. | |||||
### Disconnecting | |||||
An asynchronous connection can be terminated using: | |||||
```c | |||||
void redisAsyncDisconnect(redisAsyncContext *ac); | |||||
``` | |||||
When this function is called, the connection is **not** immediately terminated. Instead, new | |||||
commands are no longer accepted and the connection is only terminated when all pending commands | |||||
have been written to the socket, their respective replies have been read and their respective | |||||
callbacks have been executed. After this, the disconnection callback is executed with the | |||||
`REDIS_OK` status and the context object is freed. | |||||
### Hooking it up to event library *X* | |||||
There are a few hooks that need to be set on the context object after it is created. | |||||
See the `adapters/` directory for bindings to *libev* and *libevent*. | |||||
## Reply parsing API | |||||
Hiredis comes with a reply parsing API that makes it easy for writing higher | |||||
level language bindings. | |||||
The reply parsing API consists of the following functions: | |||||
```c | |||||
redisReader *redisReaderCreate(void); | |||||
void redisReaderFree(redisReader *reader); | |||||
int redisReaderFeed(redisReader *reader, const char *buf, size_t len); | |||||
int redisReaderGetReply(redisReader *reader, void **reply); | |||||
``` | |||||
The same set of functions are used internally by hiredis when creating a | |||||
normal Redis context, the above API just exposes it to the user for a direct | |||||
usage. | |||||
### Usage | |||||
The function `redisReaderCreate` creates a `redisReader` structure that holds a | |||||
buffer with unparsed data and state for the protocol parser. | |||||
Incoming data -- most likely from a socket -- can be placed in the internal | |||||
buffer of the `redisReader` using `redisReaderFeed`. This function will make a | |||||
copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed | |||||
when `redisReaderGetReply` is called. This function returns an integer status | |||||
and a reply object (as described above) via `void **reply`. The returned status | |||||
can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went | |||||
wrong (either a protocol error, or an out of memory error). | |||||
The parser limits the level of nesting for multi bulk payloads to 7. If the | |||||
multi bulk nesting level is higher than this, the parser returns an error. | |||||
### Customizing replies | |||||
The function `redisReaderGetReply` creates `redisReply` and makes the function | |||||
argument `reply` point to the created `redisReply` variable. For instance, if | |||||
the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` | |||||
will hold the status as a vanilla C string. However, the functions that are | |||||
responsible for creating instances of the `redisReply` can be customized by | |||||
setting the `fn` field on the `redisReader` struct. This should be done | |||||
immediately after creating the `redisReader`. | |||||
For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) | |||||
uses customized reply object functions to create Ruby objects. | |||||
### Reader max buffer | |||||
Both when using the Reader API directly or when using it indirectly via a | |||||
normal Redis context, the redisReader structure uses a buffer in order to | |||||
accumulate data from the server. | |||||
Usually this buffer is destroyed when it is empty and is larger than 16 | |||||
KiB in order to avoid wasting memory in unused buffers | |||||
However when working with very big payloads destroying the buffer may slow | |||||
down performances considerably, so it is possible to modify the max size of | |||||
an idle buffer changing the value of the `maxbuf` field of the reader structure | |||||
to the desired value. The special value of 0 means that there is no maximum | |||||
value for an idle buffer, so the buffer will never get freed. | |||||
For instance if you have a normal Redis context you can set the maximum idle | |||||
buffer to zero (unlimited) just with: | |||||
```c | |||||
context->reader->maxbuf = 0; | |||||
``` | |||||
This should be done only in order to maximize performances when working with | |||||
large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again | |||||
as soon as possible in order to prevent allocation of useless memory. | |||||
## SSL/TLS Support | |||||
### Building | |||||
SSL/TLS support is not built by default and requires an explicit flag: | |||||
make USE_SSL=1 | |||||
This requires OpenSSL development package (e.g. including header files to be | |||||
available. | |||||
When enabled, SSL/TLS support is built into extra `libhiredis_ssl.a` and | |||||
`libhiredis_ssl.so` static/dynamic libraries. This leaves the original libraries | |||||
unaffected so no additional dependencies are introduced. | |||||
### Using it | |||||
First, you'll need to make sure you include the SSL header file: | |||||
```c | |||||
#include "hiredis.h" | |||||
#include "hiredis_ssl.h" | |||||
``` | |||||
SSL can only be enabled on a `redisContext` connection after the connection has | |||||
been established and before any command has been processed. For example: | |||||
```c | |||||
c = redisConnect('localhost', 6443); | |||||
if (c == NULL || c->err) { | |||||
/* Handle error and abort... */ | |||||
} | |||||
if (redisSecureConnection(c, | |||||
"cacertbundle.crt", /* File name of trusted CA/ca bundle file */ | |||||
"client_cert.pem", /* File name of client certificate file */ | |||||
"client_key.pem", /* File name of client privat ekey */ | |||||
"redis.mydomain.com" /* Server name to request (SNI) */ | |||||
) != REDIS_OK) { | |||||
printf("SSL error: %s\n", c->errstr); | |||||
/* Abort... */ | |||||
} | |||||
``` | |||||
You will also need to link against `libhiredis_ssl`, **in addition** to | |||||
`libhiredis` and add `-lssl -lcrypto` to satisfy its dependencies. | |||||
### OpenSSL Global State Initialization | |||||
OpenSSL needs to have certain global state initialized before it can be used. | |||||
Using `redisSecureConnection()` will handle this automatically on the first | |||||
call. | |||||
**If the calling application itself also initializes and uses OpenSSL directly, | |||||
`redisSecureConnection()` must not be used.** | |||||
Instead, use `redisInitiateSSL()` which also provides greater control over the | |||||
configuration of the SSL connection, as the caller is responsible to create a | |||||
connection context using `SSL_new()` and configure it as required. | |||||
## AUTHORS | |||||
Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and | |||||
Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license. |
@@ -0,0 +1,127 @@ | |||||
/* | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_AE_H__ | |||||
#define __HIREDIS_AE_H__ | |||||
#include <sys/types.h> | |||||
#include <ae.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
typedef struct redisAeEvents { | |||||
redisAsyncContext *context; | |||||
aeEventLoop *loop; | |||||
int fd; | |||||
int reading, writing; | |||||
} redisAeEvents; | |||||
static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { | |||||
((void)el); ((void)fd); ((void)mask); | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
redisAsyncHandleRead(e->context); | |||||
} | |||||
static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { | |||||
((void)el); ((void)fd); ((void)mask); | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
redisAsyncHandleWrite(e->context); | |||||
} | |||||
static void redisAeAddRead(void *privdata) { | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
aeEventLoop *loop = e->loop; | |||||
if (!e->reading) { | |||||
e->reading = 1; | |||||
aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); | |||||
} | |||||
} | |||||
static void redisAeDelRead(void *privdata) { | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
aeEventLoop *loop = e->loop; | |||||
if (e->reading) { | |||||
e->reading = 0; | |||||
aeDeleteFileEvent(loop,e->fd,AE_READABLE); | |||||
} | |||||
} | |||||
static void redisAeAddWrite(void *privdata) { | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
aeEventLoop *loop = e->loop; | |||||
if (!e->writing) { | |||||
e->writing = 1; | |||||
aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); | |||||
} | |||||
} | |||||
static void redisAeDelWrite(void *privdata) { | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
aeEventLoop *loop = e->loop; | |||||
if (e->writing) { | |||||
e->writing = 0; | |||||
aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); | |||||
} | |||||
} | |||||
static void redisAeCleanup(void *privdata) { | |||||
redisAeEvents *e = (redisAeEvents*)privdata; | |||||
redisAeDelRead(privdata); | |||||
redisAeDelWrite(privdata); | |||||
free(e); | |||||
} | |||||
static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisAeEvents *e; | |||||
/* Nothing should be attached when something is already attached */ | |||||
if (ac->ev.data != NULL) | |||||
return REDIS_ERR; | |||||
/* Create container for context and r/w events */ | |||||
e = (redisAeEvents*)hi_malloc(sizeof(*e)); | |||||
e->context = ac; | |||||
e->loop = loop; | |||||
e->fd = c->fd; | |||||
e->reading = e->writing = 0; | |||||
/* Register functions to start/stop listening for events */ | |||||
ac->ev.addRead = redisAeAddRead; | |||||
ac->ev.delRead = redisAeDelRead; | |||||
ac->ev.addWrite = redisAeAddWrite; | |||||
ac->ev.delWrite = redisAeDelWrite; | |||||
ac->ev.cleanup = redisAeCleanup; | |||||
ac->ev.data = e; | |||||
return REDIS_OK; | |||||
} | |||||
#endif |
@@ -0,0 +1,153 @@ | |||||
#ifndef __HIREDIS_GLIB_H__ | |||||
#define __HIREDIS_GLIB_H__ | |||||
#include <glib.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
typedef struct | |||||
{ | |||||
GSource source; | |||||
redisAsyncContext *ac; | |||||
GPollFD poll_fd; | |||||
} RedisSource; | |||||
static void | |||||
redis_source_add_read (gpointer data) | |||||
{ | |||||
RedisSource *source = (RedisSource *)data; | |||||
g_return_if_fail(source); | |||||
source->poll_fd.events |= G_IO_IN; | |||||
g_main_context_wakeup(g_source_get_context((GSource *)data)); | |||||
} | |||||
static void | |||||
redis_source_del_read (gpointer data) | |||||
{ | |||||
RedisSource *source = (RedisSource *)data; | |||||
g_return_if_fail(source); | |||||
source->poll_fd.events &= ~G_IO_IN; | |||||
g_main_context_wakeup(g_source_get_context((GSource *)data)); | |||||
} | |||||
static void | |||||
redis_source_add_write (gpointer data) | |||||
{ | |||||
RedisSource *source = (RedisSource *)data; | |||||
g_return_if_fail(source); | |||||
source->poll_fd.events |= G_IO_OUT; | |||||
g_main_context_wakeup(g_source_get_context((GSource *)data)); | |||||
} | |||||
static void | |||||
redis_source_del_write (gpointer data) | |||||
{ | |||||
RedisSource *source = (RedisSource *)data; | |||||
g_return_if_fail(source); | |||||
source->poll_fd.events &= ~G_IO_OUT; | |||||
g_main_context_wakeup(g_source_get_context((GSource *)data)); | |||||
} | |||||
static void | |||||
redis_source_cleanup (gpointer data) | |||||
{ | |||||
RedisSource *source = (RedisSource *)data; | |||||
g_return_if_fail(source); | |||||
redis_source_del_read(source); | |||||
redis_source_del_write(source); | |||||
/* | |||||
* It is not our responsibility to remove ourself from the | |||||
* current main loop. However, we will remove the GPollFD. | |||||
*/ | |||||
if (source->poll_fd.fd >= 0) { | |||||
g_source_remove_poll((GSource *)data, &source->poll_fd); | |||||
source->poll_fd.fd = -1; | |||||
} | |||||
} | |||||
static gboolean | |||||
redis_source_prepare (GSource *source, | |||||
gint *timeout_) | |||||
{ | |||||
RedisSource *redis = (RedisSource *)source; | |||||
*timeout_ = -1; | |||||
return !!(redis->poll_fd.events & redis->poll_fd.revents); | |||||
} | |||||
static gboolean | |||||
redis_source_check (GSource *source) | |||||
{ | |||||
RedisSource *redis = (RedisSource *)source; | |||||
return !!(redis->poll_fd.events & redis->poll_fd.revents); | |||||
} | |||||
static gboolean | |||||
redis_source_dispatch (GSource *source, | |||||
GSourceFunc callback, | |||||
gpointer user_data) | |||||
{ | |||||
RedisSource *redis = (RedisSource *)source; | |||||
if ((redis->poll_fd.revents & G_IO_OUT)) { | |||||
redisAsyncHandleWrite(redis->ac); | |||||
redis->poll_fd.revents &= ~G_IO_OUT; | |||||
} | |||||
if ((redis->poll_fd.revents & G_IO_IN)) { | |||||
redisAsyncHandleRead(redis->ac); | |||||
redis->poll_fd.revents &= ~G_IO_IN; | |||||
} | |||||
if (callback) { | |||||
return callback(user_data); | |||||
} | |||||
return TRUE; | |||||
} | |||||
static void | |||||
redis_source_finalize (GSource *source) | |||||
{ | |||||
RedisSource *redis = (RedisSource *)source; | |||||
if (redis->poll_fd.fd >= 0) { | |||||
g_source_remove_poll(source, &redis->poll_fd); | |||||
redis->poll_fd.fd = -1; | |||||
} | |||||
} | |||||
static GSource * | |||||
redis_source_new (redisAsyncContext *ac) | |||||
{ | |||||
static GSourceFuncs source_funcs = { | |||||
.prepare = redis_source_prepare, | |||||
.check = redis_source_check, | |||||
.dispatch = redis_source_dispatch, | |||||
.finalize = redis_source_finalize, | |||||
}; | |||||
redisContext *c = &ac->c; | |||||
RedisSource *source; | |||||
g_return_val_if_fail(ac != NULL, NULL); | |||||
source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); | |||||
source->ac = ac; | |||||
source->poll_fd.fd = c->fd; | |||||
source->poll_fd.events = 0; | |||||
source->poll_fd.revents = 0; | |||||
g_source_add_poll((GSource *)source, &source->poll_fd); | |||||
ac->ev.addRead = redis_source_add_read; | |||||
ac->ev.delRead = redis_source_del_read; | |||||
ac->ev.addWrite = redis_source_add_write; | |||||
ac->ev.delWrite = redis_source_del_write; | |||||
ac->ev.cleanup = redis_source_cleanup; | |||||
ac->ev.data = source; | |||||
return (GSource *)source; | |||||
} | |||||
#endif /* __HIREDIS_GLIB_H__ */ |
@@ -0,0 +1,81 @@ | |||||
#ifndef __HIREDIS_IVYKIS_H__ | |||||
#define __HIREDIS_IVYKIS_H__ | |||||
#include <iv.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
typedef struct redisIvykisEvents { | |||||
redisAsyncContext *context; | |||||
struct iv_fd fd; | |||||
} redisIvykisEvents; | |||||
static void redisIvykisReadEvent(void *arg) { | |||||
redisAsyncContext *context = (redisAsyncContext *)arg; | |||||
redisAsyncHandleRead(context); | |||||
} | |||||
static void redisIvykisWriteEvent(void *arg) { | |||||
redisAsyncContext *context = (redisAsyncContext *)arg; | |||||
redisAsyncHandleWrite(context); | |||||
} | |||||
static void redisIvykisAddRead(void *privdata) { | |||||
redisIvykisEvents *e = (redisIvykisEvents*)privdata; | |||||
iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); | |||||
} | |||||
static void redisIvykisDelRead(void *privdata) { | |||||
redisIvykisEvents *e = (redisIvykisEvents*)privdata; | |||||
iv_fd_set_handler_in(&e->fd, NULL); | |||||
} | |||||
static void redisIvykisAddWrite(void *privdata) { | |||||
redisIvykisEvents *e = (redisIvykisEvents*)privdata; | |||||
iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); | |||||
} | |||||
static void redisIvykisDelWrite(void *privdata) { | |||||
redisIvykisEvents *e = (redisIvykisEvents*)privdata; | |||||
iv_fd_set_handler_out(&e->fd, NULL); | |||||
} | |||||
static void redisIvykisCleanup(void *privdata) { | |||||
redisIvykisEvents *e = (redisIvykisEvents*)privdata; | |||||
iv_fd_unregister(&e->fd); | |||||
free(e); | |||||
} | |||||
static int redisIvykisAttach(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisIvykisEvents *e; | |||||
/* Nothing should be attached when something is already attached */ | |||||
if (ac->ev.data != NULL) | |||||
return REDIS_ERR; | |||||
/* Create container for context and r/w events */ | |||||
e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); | |||||
e->context = ac; | |||||
/* Register functions to start/stop listening for events */ | |||||
ac->ev.addRead = redisIvykisAddRead; | |||||
ac->ev.delRead = redisIvykisDelRead; | |||||
ac->ev.addWrite = redisIvykisAddWrite; | |||||
ac->ev.delWrite = redisIvykisDelWrite; | |||||
ac->ev.cleanup = redisIvykisCleanup; | |||||
ac->ev.data = e; | |||||
/* Initialize and install read/write events */ | |||||
IV_FD_INIT(&e->fd); | |||||
e->fd.fd = c->fd; | |||||
e->fd.handler_in = redisIvykisReadEvent; | |||||
e->fd.handler_out = redisIvykisWriteEvent; | |||||
e->fd.handler_err = NULL; | |||||
e->fd.cookie = e->context; | |||||
iv_fd_register(&e->fd); | |||||
return REDIS_OK; | |||||
} | |||||
#endif |
@@ -0,0 +1,147 @@ | |||||
/* | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_LIBEV_H__ | |||||
#define __HIREDIS_LIBEV_H__ | |||||
#include <stdlib.h> | |||||
#include <sys/types.h> | |||||
#include <ev.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
typedef struct redisLibevEvents { | |||||
redisAsyncContext *context; | |||||
struct ev_loop *loop; | |||||
int reading, writing; | |||||
ev_io rev, wev; | |||||
} redisLibevEvents; | |||||
static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { | |||||
#if EV_MULTIPLICITY | |||||
((void)loop); | |||||
#endif | |||||
((void)revents); | |||||
redisLibevEvents *e = (redisLibevEvents*)watcher->data; | |||||
redisAsyncHandleRead(e->context); | |||||
} | |||||
static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { | |||||
#if EV_MULTIPLICITY | |||||
((void)loop); | |||||
#endif | |||||
((void)revents); | |||||
redisLibevEvents *e = (redisLibevEvents*)watcher->data; | |||||
redisAsyncHandleWrite(e->context); | |||||
} | |||||
static void redisLibevAddRead(void *privdata) { | |||||
redisLibevEvents *e = (redisLibevEvents*)privdata; | |||||
struct ev_loop *loop = e->loop; | |||||
((void)loop); | |||||
if (!e->reading) { | |||||
e->reading = 1; | |||||
ev_io_start(EV_A_ &e->rev); | |||||
} | |||||
} | |||||
static void redisLibevDelRead(void *privdata) { | |||||
redisLibevEvents *e = (redisLibevEvents*)privdata; | |||||
struct ev_loop *loop = e->loop; | |||||
((void)loop); | |||||
if (e->reading) { | |||||
e->reading = 0; | |||||
ev_io_stop(EV_A_ &e->rev); | |||||
} | |||||
} | |||||
static void redisLibevAddWrite(void *privdata) { | |||||
redisLibevEvents *e = (redisLibevEvents*)privdata; | |||||
struct ev_loop *loop = e->loop; | |||||
((void)loop); | |||||
if (!e->writing) { | |||||
e->writing = 1; | |||||
ev_io_start(EV_A_ &e->wev); | |||||
} | |||||
} | |||||
static void redisLibevDelWrite(void *privdata) { | |||||
redisLibevEvents *e = (redisLibevEvents*)privdata; | |||||
struct ev_loop *loop = e->loop; | |||||
((void)loop); | |||||
if (e->writing) { | |||||
e->writing = 0; | |||||
ev_io_stop(EV_A_ &e->wev); | |||||
} | |||||
} | |||||
static void redisLibevCleanup(void *privdata) { | |||||
redisLibevEvents *e = (redisLibevEvents*)privdata; | |||||
redisLibevDelRead(privdata); | |||||
redisLibevDelWrite(privdata); | |||||
free(e); | |||||
} | |||||
static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisLibevEvents *e; | |||||
/* Nothing should be attached when something is already attached */ | |||||
if (ac->ev.data != NULL) | |||||
return REDIS_ERR; | |||||
/* Create container for context and r/w events */ | |||||
e = (redisLibevEvents*)hi_malloc(sizeof(*e)); | |||||
e->context = ac; | |||||
#if EV_MULTIPLICITY | |||||
e->loop = loop; | |||||
#else | |||||
e->loop = NULL; | |||||
#endif | |||||
e->reading = e->writing = 0; | |||||
e->rev.data = e; | |||||
e->wev.data = e; | |||||
/* Register functions to start/stop listening for events */ | |||||
ac->ev.addRead = redisLibevAddRead; | |||||
ac->ev.delRead = redisLibevDelRead; | |||||
ac->ev.addWrite = redisLibevAddWrite; | |||||
ac->ev.delWrite = redisLibevDelWrite; | |||||
ac->ev.cleanup = redisLibevCleanup; | |||||
ac->ev.data = e; | |||||
/* Initialize read/write events */ | |||||
ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); | |||||
ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); | |||||
return REDIS_OK; | |||||
} | |||||
#endif |
@@ -0,0 +1,172 @@ | |||||
/* | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_LIBEVENT_H__ | |||||
#define __HIREDIS_LIBEVENT_H__ | |||||
#include <event2/event.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
#define REDIS_LIBEVENT_DELETED 0x01 | |||||
#define REDIS_LIBEVENT_ENTERED 0x02 | |||||
typedef struct redisLibeventEvents { | |||||
redisAsyncContext *context; | |||||
struct event *ev; | |||||
struct event_base *base; | |||||
struct timeval tv; | |||||
short flags; | |||||
short state; | |||||
} redisLibeventEvents; | |||||
static void redisLibeventDestroy(redisLibeventEvents *e) { | |||||
free(e); | |||||
} | |||||
static void redisLibeventHandler(int fd, short event, void *arg) { | |||||
((void)fd); | |||||
redisLibeventEvents *e = (redisLibeventEvents*)arg; | |||||
e->state |= REDIS_LIBEVENT_ENTERED; | |||||
#define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\ | |||||
redisLibeventDestroy(e);\ | |||||
return; \ | |||||
} | |||||
if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | |||||
redisAsyncHandleTimeout(e->context); | |||||
CHECK_DELETED(); | |||||
} | |||||
if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | |||||
redisAsyncHandleRead(e->context); | |||||
CHECK_DELETED(); | |||||
} | |||||
if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { | |||||
redisAsyncHandleWrite(e->context); | |||||
CHECK_DELETED(); | |||||
} | |||||
e->state &= ~REDIS_LIBEVENT_ENTERED; | |||||
#undef CHECK_DELETED | |||||
} | |||||
static void redisLibeventUpdate(void *privdata, short flag, int isRemove) { | |||||
redisLibeventEvents *e = (redisLibeventEvents *)privdata; | |||||
const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; | |||||
if (isRemove) { | |||||
if ((e->flags & flag) == 0) { | |||||
return; | |||||
} else { | |||||
e->flags &= ~flag; | |||||
} | |||||
} else { | |||||
if (e->flags & flag) { | |||||
return; | |||||
} else { | |||||
e->flags |= flag; | |||||
} | |||||
} | |||||
event_del(e->ev); | |||||
event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, | |||||
redisLibeventHandler, privdata); | |||||
event_add(e->ev, tv); | |||||
} | |||||
static void redisLibeventAddRead(void *privdata) { | |||||
redisLibeventUpdate(privdata, EV_READ, 0); | |||||
} | |||||
static void redisLibeventDelRead(void *privdata) { | |||||
redisLibeventUpdate(privdata, EV_READ, 1); | |||||
} | |||||
static void redisLibeventAddWrite(void *privdata) { | |||||
redisLibeventUpdate(privdata, EV_WRITE, 0); | |||||
} | |||||
static void redisLibeventDelWrite(void *privdata) { | |||||
redisLibeventUpdate(privdata, EV_WRITE, 1); | |||||
} | |||||
static void redisLibeventCleanup(void *privdata) { | |||||
redisLibeventEvents *e = (redisLibeventEvents*)privdata; | |||||
if (!e) { | |||||
return; | |||||
} | |||||
event_del(e->ev); | |||||
event_free(e->ev); | |||||
e->ev = NULL; | |||||
if (e->state & REDIS_LIBEVENT_ENTERED) { | |||||
e->state |= REDIS_LIBEVENT_DELETED; | |||||
} else { | |||||
redisLibeventDestroy(e); | |||||
} | |||||
} | |||||
static void redisLibeventSetTimeout(void *privdata, struct timeval tv) { | |||||
redisLibeventEvents *e = (redisLibeventEvents *)privdata; | |||||
short flags = e->flags; | |||||
e->flags = 0; | |||||
e->tv = tv; | |||||
redisLibeventUpdate(e, flags, 0); | |||||
} | |||||
static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { | |||||
redisContext *c = &(ac->c); | |||||
redisLibeventEvents *e; | |||||
/* Nothing should be attached when something is already attached */ | |||||
if (ac->ev.data != NULL) | |||||
return REDIS_ERR; | |||||
/* Create container for context and r/w events */ | |||||
e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); | |||||
e->context = ac; | |||||
/* Register functions to start/stop listening for events */ | |||||
ac->ev.addRead = redisLibeventAddRead; | |||||
ac->ev.delRead = redisLibeventDelRead; | |||||
ac->ev.addWrite = redisLibeventAddWrite; | |||||
ac->ev.delWrite = redisLibeventDelWrite; | |||||
ac->ev.cleanup = redisLibeventCleanup; | |||||
ac->ev.scheduleTimer = redisLibeventSetTimeout; | |||||
ac->ev.data = e; | |||||
/* Initialize and install read/write events */ | |||||
e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e); | |||||
e->base = base; | |||||
return REDIS_OK; | |||||
} | |||||
#endif |
@@ -0,0 +1,119 @@ | |||||
#ifndef __HIREDIS_LIBUV_H__ | |||||
#define __HIREDIS_LIBUV_H__ | |||||
#include <stdlib.h> | |||||
#include <uv.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
#include <string.h> | |||||
typedef struct redisLibuvEvents { | |||||
redisAsyncContext* context; | |||||
uv_poll_t handle; | |||||
int events; | |||||
} redisLibuvEvents; | |||||
static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)handle->data; | |||||
int ev = (status ? p->events : events); | |||||
if (p->context != NULL && (ev & UV_READABLE)) { | |||||
redisAsyncHandleRead(p->context); | |||||
} | |||||
if (p->context != NULL && (ev & UV_WRITABLE)) { | |||||
redisAsyncHandleWrite(p->context); | |||||
} | |||||
} | |||||
static void redisLibuvAddRead(void *privdata) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)privdata; | |||||
p->events |= UV_READABLE; | |||||
uv_poll_start(&p->handle, p->events, redisLibuvPoll); | |||||
} | |||||
static void redisLibuvDelRead(void *privdata) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)privdata; | |||||
p->events &= ~UV_READABLE; | |||||
if (p->events) { | |||||
uv_poll_start(&p->handle, p->events, redisLibuvPoll); | |||||
} else { | |||||
uv_poll_stop(&p->handle); | |||||
} | |||||
} | |||||
static void redisLibuvAddWrite(void *privdata) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)privdata; | |||||
p->events |= UV_WRITABLE; | |||||
uv_poll_start(&p->handle, p->events, redisLibuvPoll); | |||||
} | |||||
static void redisLibuvDelWrite(void *privdata) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)privdata; | |||||
p->events &= ~UV_WRITABLE; | |||||
if (p->events) { | |||||
uv_poll_start(&p->handle, p->events, redisLibuvPoll); | |||||
} else { | |||||
uv_poll_stop(&p->handle); | |||||
} | |||||
} | |||||
static void on_close(uv_handle_t* handle) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)handle->data; | |||||
free(p); | |||||
} | |||||
static void redisLibuvCleanup(void *privdata) { | |||||
redisLibuvEvents* p = (redisLibuvEvents*)privdata; | |||||
p->context = NULL; // indicate that context might no longer exist | |||||
uv_close((uv_handle_t*)&p->handle, on_close); | |||||
} | |||||
static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { | |||||
redisContext *c = &(ac->c); | |||||
if (ac->ev.data != NULL) { | |||||
return REDIS_ERR; | |||||
} | |||||
ac->ev.addRead = redisLibuvAddRead; | |||||
ac->ev.delRead = redisLibuvDelRead; | |||||
ac->ev.addWrite = redisLibuvAddWrite; | |||||
ac->ev.delWrite = redisLibuvDelWrite; | |||||
ac->ev.cleanup = redisLibuvCleanup; | |||||
redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); | |||||
if (!p) { | |||||
return REDIS_ERR; | |||||
} | |||||
memset(p, 0, sizeof(*p)); | |||||
if (uv_poll_init(loop, &p->handle, c->fd) != 0) { | |||||
return REDIS_ERR; | |||||
} | |||||
ac->ev.data = p; | |||||
p->handle.data = p; | |||||
p->context = ac; | |||||
return REDIS_OK; | |||||
} | |||||
#endif |
@@ -0,0 +1,114 @@ | |||||
// | |||||
// Created by Дмитрий Бахвалов on 13.07.15. | |||||
// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. | |||||
// | |||||
#ifndef __HIREDIS_MACOSX_H__ | |||||
#define __HIREDIS_MACOSX_H__ | |||||
#include <CoreFoundation/CoreFoundation.h> | |||||
#include "../hiredis.h" | |||||
#include "../async.h" | |||||
typedef struct { | |||||
redisAsyncContext *context; | |||||
CFSocketRef socketRef; | |||||
CFRunLoopSourceRef sourceRef; | |||||
} RedisRunLoop; | |||||
static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { | |||||
if( redisRunLoop != NULL ) { | |||||
if( redisRunLoop->sourceRef != NULL ) { | |||||
CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); | |||||
CFRelease(redisRunLoop->sourceRef); | |||||
} | |||||
if( redisRunLoop->socketRef != NULL ) { | |||||
CFSocketInvalidate(redisRunLoop->socketRef); | |||||
CFRelease(redisRunLoop->socketRef); | |||||
} | |||||
free(redisRunLoop); | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
static void redisMacOSAddRead(void *privdata) { | |||||
RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | |||||
CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); | |||||
} | |||||
static void redisMacOSDelRead(void *privdata) { | |||||
RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | |||||
CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); | |||||
} | |||||
static void redisMacOSAddWrite(void *privdata) { | |||||
RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | |||||
CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); | |||||
} | |||||
static void redisMacOSDelWrite(void *privdata) { | |||||
RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | |||||
CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); | |||||
} | |||||
static void redisMacOSCleanup(void *privdata) { | |||||
RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; | |||||
freeRedisRunLoop(redisRunLoop); | |||||
} | |||||
static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { | |||||
redisAsyncContext* context = (redisAsyncContext*) info; | |||||
switch (callbackType) { | |||||
case kCFSocketReadCallBack: | |||||
redisAsyncHandleRead(context); | |||||
break; | |||||
case kCFSocketWriteCallBack: | |||||
redisAsyncHandleWrite(context); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { | |||||
redisContext *redisCtx = &(redisAsyncCtx->c); | |||||
/* Nothing should be attached when something is already attached */ | |||||
if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; | |||||
RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop)); | |||||
if( !redisRunLoop ) return REDIS_ERR; | |||||
/* Setup redis stuff */ | |||||
redisRunLoop->context = redisAsyncCtx; | |||||
redisAsyncCtx->ev.addRead = redisMacOSAddRead; | |||||
redisAsyncCtx->ev.delRead = redisMacOSDelRead; | |||||
redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; | |||||
redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; | |||||
redisAsyncCtx->ev.cleanup = redisMacOSCleanup; | |||||
redisAsyncCtx->ev.data = redisRunLoop; | |||||
/* Initialize and install read/write events */ | |||||
CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; | |||||
redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, | |||||
kCFSocketReadCallBack | kCFSocketWriteCallBack, | |||||
redisMacOSAsyncCallback, | |||||
&socketCtx); | |||||
if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); | |||||
redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); | |||||
if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); | |||||
CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); | |||||
return REDIS_OK; | |||||
} | |||||
#endif | |||||
@@ -0,0 +1,135 @@ | |||||
/*- | |||||
* Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch> | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_QT_H__ | |||||
#define __HIREDIS_QT_H__ | |||||
#include <QSocketNotifier> | |||||
#include "../async.h" | |||||
static void RedisQtAddRead(void *); | |||||
static void RedisQtDelRead(void *); | |||||
static void RedisQtAddWrite(void *); | |||||
static void RedisQtDelWrite(void *); | |||||
static void RedisQtCleanup(void *); | |||||
class RedisQtAdapter : public QObject { | |||||
Q_OBJECT | |||||
friend | |||||
void RedisQtAddRead(void * adapter) { | |||||
RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | |||||
a->addRead(); | |||||
} | |||||
friend | |||||
void RedisQtDelRead(void * adapter) { | |||||
RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | |||||
a->delRead(); | |||||
} | |||||
friend | |||||
void RedisQtAddWrite(void * adapter) { | |||||
RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | |||||
a->addWrite(); | |||||
} | |||||
friend | |||||
void RedisQtDelWrite(void * adapter) { | |||||
RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | |||||
a->delWrite(); | |||||
} | |||||
friend | |||||
void RedisQtCleanup(void * adapter) { | |||||
RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter); | |||||
a->cleanup(); | |||||
} | |||||
public: | |||||
RedisQtAdapter(QObject * parent = 0) | |||||
: QObject(parent), m_ctx(0), m_read(0), m_write(0) { } | |||||
~RedisQtAdapter() { | |||||
if (m_ctx != 0) { | |||||
m_ctx->ev.data = NULL; | |||||
} | |||||
} | |||||
int setContext(redisAsyncContext * ac) { | |||||
if (ac->ev.data != NULL) { | |||||
return REDIS_ERR; | |||||
} | |||||
m_ctx = ac; | |||||
m_ctx->ev.data = this; | |||||
m_ctx->ev.addRead = RedisQtAddRead; | |||||
m_ctx->ev.delRead = RedisQtDelRead; | |||||
m_ctx->ev.addWrite = RedisQtAddWrite; | |||||
m_ctx->ev.delWrite = RedisQtDelWrite; | |||||
m_ctx->ev.cleanup = RedisQtCleanup; | |||||
return REDIS_OK; | |||||
} | |||||
private: | |||||
void addRead() { | |||||
if (m_read) return; | |||||
m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); | |||||
connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); | |||||
} | |||||
void delRead() { | |||||
if (!m_read) return; | |||||
delete m_read; | |||||
m_read = 0; | |||||
} | |||||
void addWrite() { | |||||
if (m_write) return; | |||||
m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); | |||||
connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); | |||||
} | |||||
void delWrite() { | |||||
if (!m_write) return; | |||||
delete m_write; | |||||
m_write = 0; | |||||
} | |||||
void cleanup() { | |||||
delRead(); | |||||
delWrite(); | |||||
} | |||||
private slots: | |||||
void read() { redisAsyncHandleRead(m_ctx); } | |||||
void write() { redisAsyncHandleWrite(m_ctx); } | |||||
private: | |||||
redisAsyncContext * m_ctx; | |||||
QSocketNotifier * m_read; | |||||
QSocketNotifier * m_write; | |||||
}; | |||||
#endif /* !__HIREDIS_QT_H__ */ |
@@ -0,0 +1,65 @@ | |||||
/* | |||||
* Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "fmacros.h" | |||||
#include "alloc.h" | |||||
#include <string.h> | |||||
void *hi_malloc(size_t size) { | |||||
void *ptr = malloc(size); | |||||
if (ptr == NULL) | |||||
HIREDIS_OOM_HANDLER; | |||||
return ptr; | |||||
} | |||||
void *hi_calloc(size_t nmemb, size_t size) { | |||||
void *ptr = calloc(nmemb, size); | |||||
if (ptr == NULL) | |||||
HIREDIS_OOM_HANDLER; | |||||
return ptr; | |||||
} | |||||
void *hi_realloc(void *ptr, size_t size) { | |||||
void *newptr = realloc(ptr, size); | |||||
if (newptr == NULL) | |||||
HIREDIS_OOM_HANDLER; | |||||
return newptr; | |||||
} | |||||
char *hi_strdup(const char *str) { | |||||
char *newstr = strdup(str); | |||||
if (newstr == NULL) | |||||
HIREDIS_OOM_HANDLER; | |||||
return newstr; | |||||
} |
@@ -0,0 +1,44 @@ | |||||
/* | |||||
* Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef HIREDIS_ALLOC_H | |||||
#include <stdlib.h> /* for size_t */ | |||||
#ifndef HIREDIS_OOM_HANDLER | |||||
#define HIREDIS_OOM_HANDLER abort() | |||||
#endif | |||||
void *hi_malloc(size_t size); | |||||
void *hi_calloc(size_t nmemb, size_t size); | |||||
void *hi_realloc(void *ptr, size_t size); | |||||
char *hi_strdup(const char *str); | |||||
#endif /* HIREDIS_ALLOC_H */ |
@@ -0,0 +1,24 @@ | |||||
# Appveyor configuration file for CI build of hiredis on Windows (under Cygwin) | |||||
environment: | |||||
matrix: | |||||
- CYG_BASH: C:\cygwin64\bin\bash | |||||
CC: gcc | |||||
- CYG_BASH: C:\cygwin\bin\bash | |||||
CC: gcc | |||||
CFLAGS: -m32 | |||||
CXXFLAGS: -m32 | |||||
LDFLAGS: -m32 | |||||
clone_depth: 1 | |||||
# Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail | |||||
init: | |||||
- git config --global core.autocrlf input | |||||
# Install needed build dependencies | |||||
install: | |||||
- '%CYG_BASH% -lc "cygcheck -dc cygwin"' | |||||
build_script: | |||||
- 'echo building...' | |||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; mkdir build && cd build && cmake .. -G \"Unix Makefiles\" && make VERBOSE=1"' |
@@ -0,0 +1,767 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "fmacros.h" | |||||
#include "alloc.h" | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#ifndef _MSC_VER | |||||
#include <strings.h> | |||||
#endif | |||||
#include <assert.h> | |||||
#include <ctype.h> | |||||
#include <errno.h> | |||||
#include "async.h" | |||||
#include "net.h" | |||||
#include "dict.c" | |||||
#include "sds.h" | |||||
#include "win32.h" | |||||
#include "async_private.h" | |||||
/* Forward declaration of function in hiredis.c */ | |||||
int __redisAppendCommand(redisContext *c, const char *cmd, size_t len); | |||||
/* Functions managing dictionary of callbacks for pub/sub. */ | |||||
static unsigned int callbackHash(const void *key) { | |||||
return dictGenHashFunction((const unsigned char *)key, | |||||
sdslen((const sds)key)); | |||||
} | |||||
static void *callbackValDup(void *privdata, const void *src) { | |||||
((void) privdata); | |||||
redisCallback *dup = hi_malloc(sizeof(*dup)); | |||||
memcpy(dup,src,sizeof(*dup)); | |||||
return dup; | |||||
} | |||||
static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) { | |||||
int l1, l2; | |||||
((void) privdata); | |||||
l1 = sdslen((const sds)key1); | |||||
l2 = sdslen((const sds)key2); | |||||
if (l1 != l2) return 0; | |||||
return memcmp(key1,key2,l1) == 0; | |||||
} | |||||
static void callbackKeyDestructor(void *privdata, void *key) { | |||||
((void) privdata); | |||||
sdsfree((sds)key); | |||||
} | |||||
static void callbackValDestructor(void *privdata, void *val) { | |||||
((void) privdata); | |||||
free(val); | |||||
} | |||||
static dictType callbackDict = { | |||||
callbackHash, | |||||
NULL, | |||||
callbackValDup, | |||||
callbackKeyCompare, | |||||
callbackKeyDestructor, | |||||
callbackValDestructor | |||||
}; | |||||
static redisAsyncContext *redisAsyncInitialize(redisContext *c) { | |||||
redisAsyncContext *ac; | |||||
ac = realloc(c,sizeof(redisAsyncContext)); | |||||
if (ac == NULL) | |||||
return NULL; | |||||
c = &(ac->c); | |||||
/* The regular connect functions will always set the flag REDIS_CONNECTED. | |||||
* For the async API, we want to wait until the first write event is | |||||
* received up before setting this flag, so reset it here. */ | |||||
c->flags &= ~REDIS_CONNECTED; | |||||
ac->err = 0; | |||||
ac->errstr = NULL; | |||||
ac->data = NULL; | |||||
ac->ev.data = NULL; | |||||
ac->ev.addRead = NULL; | |||||
ac->ev.delRead = NULL; | |||||
ac->ev.addWrite = NULL; | |||||
ac->ev.delWrite = NULL; | |||||
ac->ev.cleanup = NULL; | |||||
ac->ev.scheduleTimer = NULL; | |||||
ac->onConnect = NULL; | |||||
ac->onDisconnect = NULL; | |||||
ac->replies.head = NULL; | |||||
ac->replies.tail = NULL; | |||||
ac->sub.invalid.head = NULL; | |||||
ac->sub.invalid.tail = NULL; | |||||
ac->sub.channels = dictCreate(&callbackDict,NULL); | |||||
ac->sub.patterns = dictCreate(&callbackDict,NULL); | |||||
return ac; | |||||
} | |||||
/* We want the error field to be accessible directly instead of requiring | |||||
* an indirection to the redisContext struct. */ | |||||
static void __redisAsyncCopyError(redisAsyncContext *ac) { | |||||
if (!ac) | |||||
return; | |||||
redisContext *c = &(ac->c); | |||||
ac->err = c->err; | |||||
ac->errstr = c->errstr; | |||||
} | |||||
redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options) { | |||||
redisOptions myOptions = *options; | |||||
redisContext *c; | |||||
redisAsyncContext *ac; | |||||
myOptions.options |= REDIS_OPT_NONBLOCK; | |||||
c = redisConnectWithOptions(&myOptions); | |||||
if (c == NULL) { | |||||
return NULL; | |||||
} | |||||
ac = redisAsyncInitialize(c); | |||||
if (ac == NULL) { | |||||
redisFree(c); | |||||
return NULL; | |||||
} | |||||
__redisAsyncCopyError(ac); | |||||
return ac; | |||||
} | |||||
redisAsyncContext *redisAsyncConnect(const char *ip, int port) { | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_TCP(&options, ip, port); | |||||
return redisAsyncConnectWithOptions(&options); | |||||
} | |||||
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, | |||||
const char *source_addr) { | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_TCP(&options, ip, port); | |||||
options.endpoint.tcp.source_addr = source_addr; | |||||
return redisAsyncConnectWithOptions(&options); | |||||
} | |||||
redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, | |||||
const char *source_addr) { | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_TCP(&options, ip, port); | |||||
options.options |= REDIS_OPT_REUSEADDR; | |||||
options.endpoint.tcp.source_addr = source_addr; | |||||
return redisAsyncConnectWithOptions(&options); | |||||
} | |||||
redisAsyncContext *redisAsyncConnectUnix(const char *path) { | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_UNIX(&options, path); | |||||
return redisAsyncConnectWithOptions(&options); | |||||
} | |||||
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) { | |||||
if (ac->onConnect == NULL) { | |||||
ac->onConnect = fn; | |||||
/* The common way to detect an established connection is to wait for | |||||
* the first write event to be fired. This assumes the related event | |||||
* library functions are already set. */ | |||||
_EL_ADD_WRITE(ac); | |||||
return REDIS_OK; | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) { | |||||
if (ac->onDisconnect == NULL) { | |||||
ac->onDisconnect = fn; | |||||
return REDIS_OK; | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
/* Helper functions to push/shift callbacks */ | |||||
static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { | |||||
redisCallback *cb; | |||||
/* Copy callback from stack to heap */ | |||||
cb = malloc(sizeof(*cb)); | |||||
if (cb == NULL) | |||||
return REDIS_ERR_OOM; | |||||
if (source != NULL) { | |||||
memcpy(cb,source,sizeof(*cb)); | |||||
cb->next = NULL; | |||||
} | |||||
/* Store callback in list */ | |||||
if (list->head == NULL) | |||||
list->head = cb; | |||||
if (list->tail != NULL) | |||||
list->tail->next = cb; | |||||
list->tail = cb; | |||||
return REDIS_OK; | |||||
} | |||||
static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) { | |||||
redisCallback *cb = list->head; | |||||
if (cb != NULL) { | |||||
list->head = cb->next; | |||||
if (cb == list->tail) | |||||
list->tail = NULL; | |||||
/* Copy callback from heap to stack */ | |||||
if (target != NULL) | |||||
memcpy(target,cb,sizeof(*cb)); | |||||
free(cb); | |||||
return REDIS_OK; | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) { | |||||
redisContext *c = &(ac->c); | |||||
if (cb->fn != NULL) { | |||||
c->flags |= REDIS_IN_CALLBACK; | |||||
cb->fn(ac,reply,cb->privdata); | |||||
c->flags &= ~REDIS_IN_CALLBACK; | |||||
} | |||||
} | |||||
/* Helper function to free the context. */ | |||||
static void __redisAsyncFree(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisCallback cb; | |||||
dictIterator *it; | |||||
dictEntry *de; | |||||
/* Execute pending callbacks with NULL reply. */ | |||||
while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK) | |||||
__redisRunCallback(ac,&cb,NULL); | |||||
/* Execute callbacks for invalid commands */ | |||||
while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK) | |||||
__redisRunCallback(ac,&cb,NULL); | |||||
/* Run subscription callbacks callbacks with NULL reply */ | |||||
it = dictGetIterator(ac->sub.channels); | |||||
while ((de = dictNext(it)) != NULL) | |||||
__redisRunCallback(ac,dictGetEntryVal(de),NULL); | |||||
dictReleaseIterator(it); | |||||
dictRelease(ac->sub.channels); | |||||
it = dictGetIterator(ac->sub.patterns); | |||||
while ((de = dictNext(it)) != NULL) | |||||
__redisRunCallback(ac,dictGetEntryVal(de),NULL); | |||||
dictReleaseIterator(it); | |||||
dictRelease(ac->sub.patterns); | |||||
/* Signal event lib to clean up */ | |||||
_EL_CLEANUP(ac); | |||||
/* Execute disconnect callback. When redisAsyncFree() initiated destroying | |||||
* this context, the status will always be REDIS_OK. */ | |||||
if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) { | |||||
if (c->flags & REDIS_FREEING) { | |||||
ac->onDisconnect(ac,REDIS_OK); | |||||
} else { | |||||
ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR); | |||||
} | |||||
} | |||||
/* Cleanup self */ | |||||
redisFree(c); | |||||
} | |||||
/* Free the async context. When this function is called from a callback, | |||||
* control needs to be returned to redisProcessCallbacks() before actual | |||||
* free'ing. To do so, a flag is set on the context which is picked up by | |||||
* redisProcessCallbacks(). Otherwise, the context is immediately free'd. */ | |||||
void redisAsyncFree(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
c->flags |= REDIS_FREEING; | |||||
if (!(c->flags & REDIS_IN_CALLBACK)) | |||||
__redisAsyncFree(ac); | |||||
} | |||||
/* Helper function to make the disconnect happen and clean up. */ | |||||
void __redisAsyncDisconnect(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
/* Make sure error is accessible if there is any */ | |||||
__redisAsyncCopyError(ac); | |||||
if (ac->err == 0) { | |||||
/* For clean disconnects, there should be no pending callbacks. */ | |||||
int ret = __redisShiftCallback(&ac->replies,NULL); | |||||
assert(ret == REDIS_ERR); | |||||
} else { | |||||
/* Disconnection is caused by an error, make sure that pending | |||||
* callbacks cannot call new commands. */ | |||||
c->flags |= REDIS_DISCONNECTING; | |||||
} | |||||
/* cleanup event library on disconnect. | |||||
* this is safe to call multiple times */ | |||||
_EL_CLEANUP(ac); | |||||
/* For non-clean disconnects, __redisAsyncFree() will execute pending | |||||
* callbacks with a NULL-reply. */ | |||||
if (!(c->flags & REDIS_NO_AUTO_FREE)) { | |||||
__redisAsyncFree(ac); | |||||
} | |||||
} | |||||
/* Tries to do a clean disconnect from Redis, meaning it stops new commands | |||||
* from being issued, but tries to flush the output buffer and execute | |||||
* callbacks for all remaining replies. When this function is called from a | |||||
* callback, there might be more replies and we can safely defer disconnecting | |||||
* to redisProcessCallbacks(). Otherwise, we can only disconnect immediately | |||||
* when there are no pending callbacks. */ | |||||
void redisAsyncDisconnect(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
c->flags |= REDIS_DISCONNECTING; | |||||
/** unset the auto-free flag here, because disconnect undoes this */ | |||||
c->flags &= ~REDIS_NO_AUTO_FREE; | |||||
if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) | |||||
__redisAsyncDisconnect(ac); | |||||
} | |||||
static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) { | |||||
redisContext *c = &(ac->c); | |||||
dict *callbacks; | |||||
redisCallback *cb; | |||||
dictEntry *de; | |||||
int pvariant; | |||||
char *stype; | |||||
sds sname; | |||||
/* Custom reply functions are not supported for pub/sub. This will fail | |||||
* very hard when they are used... */ | |||||
if (reply->type == REDIS_REPLY_ARRAY) { | |||||
assert(reply->elements >= 2); | |||||
assert(reply->element[0]->type == REDIS_REPLY_STRING); | |||||
stype = reply->element[0]->str; | |||||
pvariant = (tolower(stype[0]) == 'p') ? 1 : 0; | |||||
if (pvariant) | |||||
callbacks = ac->sub.patterns; | |||||
else | |||||
callbacks = ac->sub.channels; | |||||
/* Locate the right callback */ | |||||
assert(reply->element[1]->type == REDIS_REPLY_STRING); | |||||
sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len); | |||||
de = dictFind(callbacks,sname); | |||||
if (de != NULL) { | |||||
cb = dictGetEntryVal(de); | |||||
/* If this is an subscribe reply decrease pending counter. */ | |||||
if (strcasecmp(stype+pvariant,"subscribe") == 0) { | |||||
cb->pending_subs -= 1; | |||||
} | |||||
memcpy(dstcb,cb,sizeof(*dstcb)); | |||||
/* If this is an unsubscribe message, remove it. */ | |||||
if (strcasecmp(stype+pvariant,"unsubscribe") == 0) { | |||||
if (cb->pending_subs == 0) | |||||
dictDelete(callbacks,sname); | |||||
/* If this was the last unsubscribe message, revert to | |||||
* non-subscribe mode. */ | |||||
assert(reply->element[2]->type == REDIS_REPLY_INTEGER); | |||||
/* Unset subscribed flag only when no pipelined pending subscribe. */ | |||||
if (reply->element[2]->integer == 0 | |||||
&& dictSize(ac->sub.channels) == 0 | |||||
&& dictSize(ac->sub.patterns) == 0) | |||||
c->flags &= ~REDIS_SUBSCRIBED; | |||||
} | |||||
} | |||||
sdsfree(sname); | |||||
} else { | |||||
/* Shift callback for invalid commands. */ | |||||
__redisShiftCallback(&ac->sub.invalid,dstcb); | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
void redisProcessCallbacks(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisCallback cb = {NULL, NULL, 0, NULL}; | |||||
void *reply = NULL; | |||||
int status; | |||||
while((status = redisGetReply(c,&reply)) == REDIS_OK) { | |||||
if (reply == NULL) { | |||||
/* When the connection is being disconnected and there are | |||||
* no more replies, this is the cue to really disconnect. */ | |||||
if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0 | |||||
&& ac->replies.head == NULL) { | |||||
__redisAsyncDisconnect(ac); | |||||
return; | |||||
} | |||||
/* If monitor mode, repush callback */ | |||||
if(c->flags & REDIS_MONITORING) { | |||||
__redisPushCallback(&ac->replies,&cb); | |||||
} | |||||
/* When the connection is not being disconnected, simply stop | |||||
* trying to get replies and wait for the next loop tick. */ | |||||
break; | |||||
} | |||||
/* Even if the context is subscribed, pending regular callbacks will | |||||
* get a reply before pub/sub messages arrive. */ | |||||
if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) { | |||||
/* | |||||
* A spontaneous reply in a not-subscribed context can be the error | |||||
* reply that is sent when a new connection exceeds the maximum | |||||
* number of allowed connections on the server side. | |||||
* | |||||
* This is seen as an error instead of a regular reply because the | |||||
* server closes the connection after sending it. | |||||
* | |||||
* To prevent the error from being overwritten by an EOF error the | |||||
* connection is closed here. See issue #43. | |||||
* | |||||
* Another possibility is that the server is loading its dataset. | |||||
* In this case we also want to close the connection, and have the | |||||
* user wait until the server is ready to take our request. | |||||
*/ | |||||
if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) { | |||||
c->err = REDIS_ERR_OTHER; | |||||
snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str); | |||||
c->reader->fn->freeObject(reply); | |||||
__redisAsyncDisconnect(ac); | |||||
return; | |||||
} | |||||
/* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */ | |||||
assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING)); | |||||
if(c->flags & REDIS_SUBSCRIBED) | |||||
__redisGetSubscribeCallback(ac,reply,&cb); | |||||
} | |||||
if (cb.fn != NULL) { | |||||
__redisRunCallback(ac,&cb,reply); | |||||
c->reader->fn->freeObject(reply); | |||||
/* Proceed with free'ing when redisAsyncFree() was called. */ | |||||
if (c->flags & REDIS_FREEING) { | |||||
__redisAsyncFree(ac); | |||||
return; | |||||
} | |||||
} else { | |||||
/* No callback for this reply. This can either be a NULL callback, | |||||
* or there were no callbacks to begin with. Either way, don't | |||||
* abort with an error, but simply ignore it because the client | |||||
* doesn't know what the server will spit out over the wire. */ | |||||
c->reader->fn->freeObject(reply); | |||||
} | |||||
} | |||||
/* Disconnect when there was an error reading the reply */ | |||||
if (status != REDIS_OK) | |||||
__redisAsyncDisconnect(ac); | |||||
} | |||||
/* Internal helper function to detect socket status the first time a read or | |||||
* write event fires. When connecting was not successful, the connect callback | |||||
* is called with a REDIS_ERR status and the context is free'd. */ | |||||
static int __redisAsyncHandleConnect(redisAsyncContext *ac) { | |||||
int completed = 0; | |||||
redisContext *c = &(ac->c); | |||||
if (redisCheckConnectDone(c, &completed) == REDIS_ERR) { | |||||
/* Error! */ | |||||
redisCheckSocketError(c); | |||||
if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); | |||||
__redisAsyncDisconnect(ac); | |||||
return REDIS_ERR; | |||||
} else if (completed == 1) { | |||||
/* connected! */ | |||||
if (ac->onConnect) ac->onConnect(ac, REDIS_OK); | |||||
c->flags |= REDIS_CONNECTED; | |||||
return REDIS_OK; | |||||
} else { | |||||
return REDIS_OK; | |||||
} | |||||
} | |||||
void redisAsyncRead(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
if (redisBufferRead(c) == REDIS_ERR) { | |||||
__redisAsyncDisconnect(ac); | |||||
} else { | |||||
/* Always re-schedule reads */ | |||||
_EL_ADD_READ(ac); | |||||
redisProcessCallbacks(ac); | |||||
} | |||||
} | |||||
/* This function should be called when the socket is readable. | |||||
* It processes all replies that can be read and executes their callbacks. | |||||
*/ | |||||
void redisAsyncHandleRead(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
if (!(c->flags & REDIS_CONNECTED)) { | |||||
/* Abort connect was not successful. */ | |||||
if (__redisAsyncHandleConnect(ac) != REDIS_OK) | |||||
return; | |||||
/* Try again later when the context is still not connected. */ | |||||
if (!(c->flags & REDIS_CONNECTED)) | |||||
return; | |||||
} | |||||
c->funcs->async_read(ac); | |||||
} | |||||
void redisAsyncWrite(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
int done = 0; | |||||
if (redisBufferWrite(c,&done) == REDIS_ERR) { | |||||
__redisAsyncDisconnect(ac); | |||||
} else { | |||||
/* Continue writing when not done, stop writing otherwise */ | |||||
if (!done) | |||||
_EL_ADD_WRITE(ac); | |||||
else | |||||
_EL_DEL_WRITE(ac); | |||||
/* Always schedule reads after writes */ | |||||
_EL_ADD_READ(ac); | |||||
} | |||||
} | |||||
void redisAsyncHandleWrite(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
if (!(c->flags & REDIS_CONNECTED)) { | |||||
/* Abort connect was not successful. */ | |||||
if (__redisAsyncHandleConnect(ac) != REDIS_OK) | |||||
return; | |||||
/* Try again later when the context is still not connected. */ | |||||
if (!(c->flags & REDIS_CONNECTED)) | |||||
return; | |||||
} | |||||
c->funcs->async_write(ac); | |||||
} | |||||
void __redisSetError(redisContext *c, int type, const char *str); | |||||
void redisAsyncHandleTimeout(redisAsyncContext *ac) { | |||||
redisContext *c = &(ac->c); | |||||
redisCallback cb; | |||||
if ((c->flags & REDIS_CONNECTED) && ac->replies.head == NULL) { | |||||
/* Nothing to do - just an idle timeout */ | |||||
return; | |||||
} | |||||
if (!c->err) { | |||||
__redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout"); | |||||
} | |||||
if (!(c->flags & REDIS_CONNECTED) && ac->onConnect) { | |||||
ac->onConnect(ac, REDIS_ERR); | |||||
} | |||||
while (__redisShiftCallback(&ac->replies, &cb) == REDIS_OK) { | |||||
__redisRunCallback(ac, &cb, NULL); | |||||
} | |||||
/** | |||||
* TODO: Don't automatically sever the connection, | |||||
* rather, allow to ignore <x> responses before the queue is clear | |||||
*/ | |||||
__redisAsyncDisconnect(ac); | |||||
} | |||||
/* Sets a pointer to the first argument and its length starting at p. Returns | |||||
* the number of bytes to skip to get to the following argument. */ | |||||
static const char *nextArgument(const char *start, const char **str, size_t *len) { | |||||
const char *p = start; | |||||
if (p[0] != '$') { | |||||
p = strchr(p,'$'); | |||||
if (p == NULL) return NULL; | |||||
} | |||||
*len = (int)strtol(p+1,NULL,10); | |||||
p = strchr(p,'\r'); | |||||
assert(p); | |||||
*str = p+2; | |||||
return p+2+(*len)+2; | |||||
} | |||||
/* Helper function for the redisAsyncCommand* family of functions. Writes a | |||||
* formatted command to the output buffer and registers the provided callback | |||||
* function with the context. */ | |||||
static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { | |||||
redisContext *c = &(ac->c); | |||||
redisCallback cb; | |||||
struct dict *cbdict; | |||||
dictEntry *de; | |||||
redisCallback *existcb; | |||||
int pvariant, hasnext; | |||||
const char *cstr, *astr; | |||||
size_t clen, alen; | |||||
const char *p; | |||||
sds sname; | |||||
int ret; | |||||
/* Don't accept new commands when the connection is about to be closed. */ | |||||
if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR; | |||||
/* Setup callback */ | |||||
cb.fn = fn; | |||||
cb.privdata = privdata; | |||||
cb.pending_subs = 1; | |||||
/* Find out which command will be appended. */ | |||||
p = nextArgument(cmd,&cstr,&clen); | |||||
assert(p != NULL); | |||||
hasnext = (p[0] == '$'); | |||||
pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0; | |||||
cstr += pvariant; | |||||
clen -= pvariant; | |||||
if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) { | |||||
c->flags |= REDIS_SUBSCRIBED; | |||||
/* Add every channel/pattern to the list of subscription callbacks. */ | |||||
while ((p = nextArgument(p,&astr,&alen)) != NULL) { | |||||
sname = sdsnewlen(astr,alen); | |||||
if (pvariant) | |||||
cbdict = ac->sub.patterns; | |||||
else | |||||
cbdict = ac->sub.channels; | |||||
de = dictFind(cbdict,sname); | |||||
if (de != NULL) { | |||||
existcb = dictGetEntryVal(de); | |||||
cb.pending_subs = existcb->pending_subs + 1; | |||||
} | |||||
ret = dictReplace(cbdict,sname,&cb); | |||||
if (ret == 0) sdsfree(sname); | |||||
} | |||||
} else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) { | |||||
/* It is only useful to call (P)UNSUBSCRIBE when the context is | |||||
* subscribed to one or more channels or patterns. */ | |||||
if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR; | |||||
/* (P)UNSUBSCRIBE does not have its own response: every channel or | |||||
* pattern that is unsubscribed will receive a message. This means we | |||||
* should not append a callback function for this command. */ | |||||
} else if(strncasecmp(cstr,"monitor\r\n",9) == 0) { | |||||
/* Set monitor flag and push callback */ | |||||
c->flags |= REDIS_MONITORING; | |||||
__redisPushCallback(&ac->replies,&cb); | |||||
} else { | |||||
if (c->flags & REDIS_SUBSCRIBED) | |||||
/* This will likely result in an error reply, but it needs to be | |||||
* received and passed to the callback. */ | |||||
__redisPushCallback(&ac->sub.invalid,&cb); | |||||
else | |||||
__redisPushCallback(&ac->replies,&cb); | |||||
} | |||||
__redisAppendCommand(c,cmd,len); | |||||
/* Always schedule a write when the write buffer is non-empty */ | |||||
_EL_ADD_WRITE(ac); | |||||
return REDIS_OK; | |||||
} | |||||
int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) { | |||||
char *cmd; | |||||
int len; | |||||
int status; | |||||
len = redisvFormatCommand(&cmd,format,ap); | |||||
/* We don't want to pass -1 or -2 to future functions as a length. */ | |||||
if (len < 0) | |||||
return REDIS_ERR; | |||||
status = __redisAsyncCommand(ac,fn,privdata,cmd,len); | |||||
free(cmd); | |||||
return status; | |||||
} | |||||
int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) { | |||||
va_list ap; | |||||
int status; | |||||
va_start(ap,format); | |||||
status = redisvAsyncCommand(ac,fn,privdata,format,ap); | |||||
va_end(ap); | |||||
return status; | |||||
} | |||||
int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { | |||||
sds cmd; | |||||
int len; | |||||
int status; | |||||
len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); | |||||
if (len < 0) | |||||
return REDIS_ERR; | |||||
status = __redisAsyncCommand(ac,fn,privdata,cmd,len); | |||||
sdsfree(cmd); | |||||
return status; | |||||
} | |||||
int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { | |||||
int status = __redisAsyncCommand(ac,fn,privdata,cmd,len); | |||||
return status; | |||||
} | |||||
void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) { | |||||
if (!ac->c.timeout) { | |||||
ac->c.timeout = hi_calloc(1, sizeof(tv)); | |||||
} | |||||
if (tv.tv_sec == ac->c.timeout->tv_sec && | |||||
tv.tv_usec == ac->c.timeout->tv_usec) { | |||||
return; | |||||
} | |||||
*ac->c.timeout = tv; | |||||
} |
@@ -0,0 +1,142 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_ASYNC_H | |||||
#define __HIREDIS_ASYNC_H | |||||
#include "hiredis.h" | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ | |||||
struct dict; /* dictionary header is included in async.c */ | |||||
/* Reply callback prototype and container */ | |||||
typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); | |||||
typedef struct redisCallback { | |||||
struct redisCallback *next; /* simple singly linked list */ | |||||
redisCallbackFn *fn; | |||||
int pending_subs; | |||||
void *privdata; | |||||
} redisCallback; | |||||
/* List of callbacks for either regular replies or pub/sub */ | |||||
typedef struct redisCallbackList { | |||||
redisCallback *head, *tail; | |||||
} redisCallbackList; | |||||
/* Connection callback prototypes */ | |||||
typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); | |||||
typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); | |||||
typedef void(redisTimerCallback)(void *timer, void *privdata); | |||||
/* Context for an async connection to Redis */ | |||||
typedef struct redisAsyncContext { | |||||
/* Hold the regular context, so it can be realloc'ed. */ | |||||
redisContext c; | |||||
/* Setup error flags so they can be used directly. */ | |||||
int err; | |||||
char *errstr; | |||||
/* Not used by hiredis */ | |||||
void *data; | |||||
/* Event library data and hooks */ | |||||
struct { | |||||
void *data; | |||||
/* Hooks that are called when the library expects to start | |||||
* reading/writing. These functions should be idempotent. */ | |||||
void (*addRead)(void *privdata); | |||||
void (*delRead)(void *privdata); | |||||
void (*addWrite)(void *privdata); | |||||
void (*delWrite)(void *privdata); | |||||
void (*cleanup)(void *privdata); | |||||
void (*scheduleTimer)(void *privdata, struct timeval tv); | |||||
} ev; | |||||
/* Called when either the connection is terminated due to an error or per | |||||
* user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ | |||||
redisDisconnectCallback *onDisconnect; | |||||
/* Called when the first write event was received. */ | |||||
redisConnectCallback *onConnect; | |||||
/* Regular command callbacks */ | |||||
redisCallbackList replies; | |||||
/* Address used for connect() */ | |||||
struct sockaddr *saddr; | |||||
size_t addrlen; | |||||
/* Subscription callbacks */ | |||||
struct { | |||||
redisCallbackList invalid; | |||||
struct dict *channels; | |||||
struct dict *patterns; | |||||
} sub; | |||||
} redisAsyncContext; | |||||
/* Functions that proxy to hiredis */ | |||||
redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); | |||||
redisAsyncContext *redisAsyncConnect(const char *ip, int port); | |||||
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); | |||||
redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, | |||||
const char *source_addr); | |||||
redisAsyncContext *redisAsyncConnectUnix(const char *path); | |||||
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); | |||||
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); | |||||
void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); | |||||
void redisAsyncDisconnect(redisAsyncContext *ac); | |||||
void redisAsyncFree(redisAsyncContext *ac); | |||||
/* Handle read/write events */ | |||||
void redisAsyncHandleRead(redisAsyncContext *ac); | |||||
void redisAsyncHandleWrite(redisAsyncContext *ac); | |||||
void redisAsyncHandleTimeout(redisAsyncContext *ac); | |||||
void redisAsyncRead(redisAsyncContext *ac); | |||||
void redisAsyncWrite(redisAsyncContext *ac); | |||||
/* Command functions for an async context. Write the command to the | |||||
* output buffer and register the provided callback. */ | |||||
int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); | |||||
int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); | |||||
int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); | |||||
int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
#endif |
@@ -0,0 +1,72 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_ASYNC_PRIVATE_H | |||||
#define __HIREDIS_ASYNC_PRIVATE_H | |||||
#define _EL_ADD_READ(ctx) \ | |||||
do { \ | |||||
refreshTimeout(ctx); \ | |||||
if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \ | |||||
} while (0) | |||||
#define _EL_DEL_READ(ctx) do { \ | |||||
if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \ | |||||
} while(0) | |||||
#define _EL_ADD_WRITE(ctx) \ | |||||
do { \ | |||||
refreshTimeout(ctx); \ | |||||
if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \ | |||||
} while (0) | |||||
#define _EL_DEL_WRITE(ctx) do { \ | |||||
if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \ | |||||
} while(0) | |||||
#define _EL_CLEANUP(ctx) do { \ | |||||
if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \ | |||||
ctx->ev.cleanup = NULL; \ | |||||
} while(0); | |||||
static inline void refreshTimeout(redisAsyncContext *ctx) { | |||||
if (ctx->c.timeout && ctx->ev.scheduleTimer && | |||||
(ctx->c.timeout->tv_sec || ctx->c.timeout->tv_usec)) { | |||||
ctx->ev.scheduleTimer(ctx->ev.data, *ctx->c.timeout); | |||||
// } else { | |||||
// printf("Not scheduling timer.. (tmo=%p)\n", ctx->c.timeout); | |||||
// if (ctx->c.timeout){ | |||||
// printf("tv_sec: %u. tv_usec: %u\n", ctx->c.timeout->tv_sec, | |||||
// ctx->c.timeout->tv_usec); | |||||
// } | |||||
} | |||||
} | |||||
void __redisAsyncDisconnect(redisAsyncContext *ac); | |||||
void redisProcessCallbacks(redisAsyncContext *ac); | |||||
#endif /* __HIREDIS_ASYNC_PRIVATE_H */ |
@@ -0,0 +1,339 @@ | |||||
/* Hash table implementation. | |||||
* | |||||
* This file implements in memory hash tables with insert/del/replace/find/ | |||||
* get-random-element operations. Hash tables will auto resize if needed | |||||
* tables of power of two in size are used, collisions are handled by | |||||
* chaining. See the source code for more information... :) | |||||
* | |||||
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "fmacros.h" | |||||
#include "alloc.h" | |||||
#include <stdlib.h> | |||||
#include <assert.h> | |||||
#include <limits.h> | |||||
#include "dict.h" | |||||
/* -------------------------- private prototypes ---------------------------- */ | |||||
static int _dictExpandIfNeeded(dict *ht); | |||||
static unsigned long _dictNextPower(unsigned long size); | |||||
static int _dictKeyIndex(dict *ht, const void *key); | |||||
static int _dictInit(dict *ht, dictType *type, void *privDataPtr); | |||||
/* -------------------------- hash functions -------------------------------- */ | |||||
/* Generic hash function (a popular one from Bernstein). | |||||
* I tested a few and this was the best. */ | |||||
static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { | |||||
unsigned int hash = 5381; | |||||
while (len--) | |||||
hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */ | |||||
return hash; | |||||
} | |||||
/* ----------------------------- API implementation ------------------------- */ | |||||
/* Reset an hashtable already initialized with ht_init(). | |||||
* NOTE: This function should only called by ht_destroy(). */ | |||||
static void _dictReset(dict *ht) { | |||||
ht->table = NULL; | |||||
ht->size = 0; | |||||
ht->sizemask = 0; | |||||
ht->used = 0; | |||||
} | |||||
/* Create a new hash table */ | |||||
static dict *dictCreate(dictType *type, void *privDataPtr) { | |||||
dict *ht = hi_malloc(sizeof(*ht)); | |||||
_dictInit(ht,type,privDataPtr); | |||||
return ht; | |||||
} | |||||
/* Initialize the hash table */ | |||||
static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { | |||||
_dictReset(ht); | |||||
ht->type = type; | |||||
ht->privdata = privDataPtr; | |||||
return DICT_OK; | |||||
} | |||||
/* Expand or create the hashtable */ | |||||
static int dictExpand(dict *ht, unsigned long size) { | |||||
dict n; /* the new hashtable */ | |||||
unsigned long realsize = _dictNextPower(size), i; | |||||
/* the size is invalid if it is smaller than the number of | |||||
* elements already inside the hashtable */ | |||||
if (ht->used > size) | |||||
return DICT_ERR; | |||||
_dictInit(&n, ht->type, ht->privdata); | |||||
n.size = realsize; | |||||
n.sizemask = realsize-1; | |||||
n.table = calloc(realsize,sizeof(dictEntry*)); | |||||
/* Copy all the elements from the old to the new table: | |||||
* note that if the old hash table is empty ht->size is zero, | |||||
* so dictExpand just creates an hash table. */ | |||||
n.used = ht->used; | |||||
for (i = 0; i < ht->size && ht->used > 0; i++) { | |||||
dictEntry *he, *nextHe; | |||||
if (ht->table[i] == NULL) continue; | |||||
/* For each hash entry on this slot... */ | |||||
he = ht->table[i]; | |||||
while(he) { | |||||
unsigned int h; | |||||
nextHe = he->next; | |||||
/* Get the new element index */ | |||||
h = dictHashKey(ht, he->key) & n.sizemask; | |||||
he->next = n.table[h]; | |||||
n.table[h] = he; | |||||
ht->used--; | |||||
/* Pass to the next element */ | |||||
he = nextHe; | |||||
} | |||||
} | |||||
assert(ht->used == 0); | |||||
free(ht->table); | |||||
/* Remap the new hashtable in the old */ | |||||
*ht = n; | |||||
return DICT_OK; | |||||
} | |||||
/* Add an element to the target hash table */ | |||||
static int dictAdd(dict *ht, void *key, void *val) { | |||||
int index; | |||||
dictEntry *entry; | |||||
/* Get the index of the new element, or -1 if | |||||
* the element already exists. */ | |||||
if ((index = _dictKeyIndex(ht, key)) == -1) | |||||
return DICT_ERR; | |||||
/* Allocates the memory and stores key */ | |||||
entry = hi_malloc(sizeof(*entry)); | |||||
entry->next = ht->table[index]; | |||||
ht->table[index] = entry; | |||||
/* Set the hash entry fields. */ | |||||
dictSetHashKey(ht, entry, key); | |||||
dictSetHashVal(ht, entry, val); | |||||
ht->used++; | |||||
return DICT_OK; | |||||
} | |||||
/* Add an element, discarding the old if the key already exists. | |||||
* Return 1 if the key was added from scratch, 0 if there was already an | |||||
* element with such key and dictReplace() just performed a value update | |||||
* operation. */ | |||||
static int dictReplace(dict *ht, void *key, void *val) { | |||||
dictEntry *entry, auxentry; | |||||
/* Try to add the element. If the key | |||||
* does not exists dictAdd will succeed. */ | |||||
if (dictAdd(ht, key, val) == DICT_OK) | |||||
return 1; | |||||
/* It already exists, get the entry */ | |||||
entry = dictFind(ht, key); | |||||
/* Free the old value and set the new one */ | |||||
/* Set the new value and free the old one. Note that it is important | |||||
* to do that in this order, as the value may just be exactly the same | |||||
* as the previous one. In this context, think to reference counting, | |||||
* you want to increment (set), and then decrement (free), and not the | |||||
* reverse. */ | |||||
auxentry = *entry; | |||||
dictSetHashVal(ht, entry, val); | |||||
dictFreeEntryVal(ht, &auxentry); | |||||
return 0; | |||||
} | |||||
/* Search and remove an element */ | |||||
static int dictDelete(dict *ht, const void *key) { | |||||
unsigned int h; | |||||
dictEntry *de, *prevde; | |||||
if (ht->size == 0) | |||||
return DICT_ERR; | |||||
h = dictHashKey(ht, key) & ht->sizemask; | |||||
de = ht->table[h]; | |||||
prevde = NULL; | |||||
while(de) { | |||||
if (dictCompareHashKeys(ht,key,de->key)) { | |||||
/* Unlink the element from the list */ | |||||
if (prevde) | |||||
prevde->next = de->next; | |||||
else | |||||
ht->table[h] = de->next; | |||||
dictFreeEntryKey(ht,de); | |||||
dictFreeEntryVal(ht,de); | |||||
free(de); | |||||
ht->used--; | |||||
return DICT_OK; | |||||
} | |||||
prevde = de; | |||||
de = de->next; | |||||
} | |||||
return DICT_ERR; /* not found */ | |||||
} | |||||
/* Destroy an entire hash table */ | |||||
static int _dictClear(dict *ht) { | |||||
unsigned long i; | |||||
/* Free all the elements */ | |||||
for (i = 0; i < ht->size && ht->used > 0; i++) { | |||||
dictEntry *he, *nextHe; | |||||
if ((he = ht->table[i]) == NULL) continue; | |||||
while(he) { | |||||
nextHe = he->next; | |||||
dictFreeEntryKey(ht, he); | |||||
dictFreeEntryVal(ht, he); | |||||
free(he); | |||||
ht->used--; | |||||
he = nextHe; | |||||
} | |||||
} | |||||
/* Free the table and the allocated cache structure */ | |||||
free(ht->table); | |||||
/* Re-initialize the table */ | |||||
_dictReset(ht); | |||||
return DICT_OK; /* never fails */ | |||||
} | |||||
/* Clear & Release the hash table */ | |||||
static void dictRelease(dict *ht) { | |||||
_dictClear(ht); | |||||
free(ht); | |||||
} | |||||
static dictEntry *dictFind(dict *ht, const void *key) { | |||||
dictEntry *he; | |||||
unsigned int h; | |||||
if (ht->size == 0) return NULL; | |||||
h = dictHashKey(ht, key) & ht->sizemask; | |||||
he = ht->table[h]; | |||||
while(he) { | |||||
if (dictCompareHashKeys(ht, key, he->key)) | |||||
return he; | |||||
he = he->next; | |||||
} | |||||
return NULL; | |||||
} | |||||
static dictIterator *dictGetIterator(dict *ht) { | |||||
dictIterator *iter = hi_malloc(sizeof(*iter)); | |||||
iter->ht = ht; | |||||
iter->index = -1; | |||||
iter->entry = NULL; | |||||
iter->nextEntry = NULL; | |||||
return iter; | |||||
} | |||||
static dictEntry *dictNext(dictIterator *iter) { | |||||
while (1) { | |||||
if (iter->entry == NULL) { | |||||
iter->index++; | |||||
if (iter->index >= | |||||
(signed)iter->ht->size) break; | |||||
iter->entry = iter->ht->table[iter->index]; | |||||
} else { | |||||
iter->entry = iter->nextEntry; | |||||
} | |||||
if (iter->entry) { | |||||
/* We need to save the 'next' here, the iterator user | |||||
* may delete the entry we are returning. */ | |||||
iter->nextEntry = iter->entry->next; | |||||
return iter->entry; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
static void dictReleaseIterator(dictIterator *iter) { | |||||
free(iter); | |||||
} | |||||
/* ------------------------- private functions ------------------------------ */ | |||||
/* Expand the hash table if needed */ | |||||
static int _dictExpandIfNeeded(dict *ht) { | |||||
/* If the hash table is empty expand it to the initial size, | |||||
* if the table is "full" double its size. */ | |||||
if (ht->size == 0) | |||||
return dictExpand(ht, DICT_HT_INITIAL_SIZE); | |||||
if (ht->used == ht->size) | |||||
return dictExpand(ht, ht->size*2); | |||||
return DICT_OK; | |||||
} | |||||
/* Our hash table capability is a power of two */ | |||||
static unsigned long _dictNextPower(unsigned long size) { | |||||
unsigned long i = DICT_HT_INITIAL_SIZE; | |||||
if (size >= LONG_MAX) return LONG_MAX; | |||||
while(1) { | |||||
if (i >= size) | |||||
return i; | |||||
i *= 2; | |||||
} | |||||
} | |||||
/* Returns the index of a free slot that can be populated with | |||||
* an hash entry for the given 'key'. | |||||
* If the key already exists, -1 is returned. */ | |||||
static int _dictKeyIndex(dict *ht, const void *key) { | |||||
unsigned int h; | |||||
dictEntry *he; | |||||
/* Expand the hashtable if needed */ | |||||
if (_dictExpandIfNeeded(ht) == DICT_ERR) | |||||
return -1; | |||||
/* Compute the key hash value */ | |||||
h = dictHashKey(ht, key) & ht->sizemask; | |||||
/* Search if this slot does not already contain the given key */ | |||||
he = ht->table[h]; | |||||
while(he) { | |||||
if (dictCompareHashKeys(ht, key, he->key)) | |||||
return -1; | |||||
he = he->next; | |||||
} | |||||
return h; | |||||
} | |||||
@@ -0,0 +1,126 @@ | |||||
/* Hash table implementation. | |||||
* | |||||
* This file implements in memory hash tables with insert/del/replace/find/ | |||||
* get-random-element operations. Hash tables will auto resize if needed | |||||
* tables of power of two in size are used, collisions are handled by | |||||
* chaining. See the source code for more information... :) | |||||
* | |||||
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __DICT_H | |||||
#define __DICT_H | |||||
#define DICT_OK 0 | |||||
#define DICT_ERR 1 | |||||
/* Unused arguments generate annoying warnings... */ | |||||
#define DICT_NOTUSED(V) ((void) V) | |||||
typedef struct dictEntry { | |||||
void *key; | |||||
void *val; | |||||
struct dictEntry *next; | |||||
} dictEntry; | |||||
typedef struct dictType { | |||||
unsigned int (*hashFunction)(const void *key); | |||||
void *(*keyDup)(void *privdata, const void *key); | |||||
void *(*valDup)(void *privdata, const void *obj); | |||||
int (*keyCompare)(void *privdata, const void *key1, const void *key2); | |||||
void (*keyDestructor)(void *privdata, void *key); | |||||
void (*valDestructor)(void *privdata, void *obj); | |||||
} dictType; | |||||
typedef struct dict { | |||||
dictEntry **table; | |||||
dictType *type; | |||||
unsigned long size; | |||||
unsigned long sizemask; | |||||
unsigned long used; | |||||
void *privdata; | |||||
} dict; | |||||
typedef struct dictIterator { | |||||
dict *ht; | |||||
int index; | |||||
dictEntry *entry, *nextEntry; | |||||
} dictIterator; | |||||
/* This is the initial size of every hash table */ | |||||
#define DICT_HT_INITIAL_SIZE 4 | |||||
/* ------------------------------- Macros ------------------------------------*/ | |||||
#define dictFreeEntryVal(ht, entry) \ | |||||
if ((ht)->type->valDestructor) \ | |||||
(ht)->type->valDestructor((ht)->privdata, (entry)->val) | |||||
#define dictSetHashVal(ht, entry, _val_) do { \ | |||||
if ((ht)->type->valDup) \ | |||||
entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ | |||||
else \ | |||||
entry->val = (_val_); \ | |||||
} while(0) | |||||
#define dictFreeEntryKey(ht, entry) \ | |||||
if ((ht)->type->keyDestructor) \ | |||||
(ht)->type->keyDestructor((ht)->privdata, (entry)->key) | |||||
#define dictSetHashKey(ht, entry, _key_) do { \ | |||||
if ((ht)->type->keyDup) \ | |||||
entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ | |||||
else \ | |||||
entry->key = (_key_); \ | |||||
} while(0) | |||||
#define dictCompareHashKeys(ht, key1, key2) \ | |||||
(((ht)->type->keyCompare) ? \ | |||||
(ht)->type->keyCompare((ht)->privdata, key1, key2) : \ | |||||
(key1) == (key2)) | |||||
#define dictHashKey(ht, key) (ht)->type->hashFunction(key) | |||||
#define dictGetEntryKey(he) ((he)->key) | |||||
#define dictGetEntryVal(he) ((he)->val) | |||||
#define dictSlots(ht) ((ht)->size) | |||||
#define dictSize(ht) ((ht)->used) | |||||
/* API */ | |||||
static unsigned int dictGenHashFunction(const unsigned char *buf, int len); | |||||
static dict *dictCreate(dictType *type, void *privDataPtr); | |||||
static int dictExpand(dict *ht, unsigned long size); | |||||
static int dictAdd(dict *ht, void *key, void *val); | |||||
static int dictReplace(dict *ht, void *key, void *val); | |||||
static int dictDelete(dict *ht, const void *key); | |||||
static void dictRelease(dict *ht); | |||||
static dictEntry * dictFind(dict *ht, const void *key); | |||||
static dictIterator *dictGetIterator(dict *ht); | |||||
static dictEntry *dictNext(dictIterator *iter); | |||||
static void dictReleaseIterator(dictIterator *iter); | |||||
#endif /* __DICT_H */ |
@@ -0,0 +1,62 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/ae.h> | |||||
/* Put event loop in the global scope, so it can be explicitly stopped */ | |||||
static aeEventLoop *loop; | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
aeStop(loop); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
aeStop(loop); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
aeStop(loop); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
loop = aeCreateEventLoop(64); | |||||
redisAeAttach(loop, c); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
aeMain(loop); | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,73 @@ | |||||
#include <stdlib.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/glib.h> | |||||
static GMainLoop *mainloop; | |||||
static void | |||||
connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, | |||||
int status) | |||||
{ | |||||
if (status != REDIS_OK) { | |||||
g_printerr("Failed to connect: %s\n", ac->errstr); | |||||
g_main_loop_quit(mainloop); | |||||
} else { | |||||
g_printerr("Connected...\n"); | |||||
} | |||||
} | |||||
static void | |||||
disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, | |||||
int status) | |||||
{ | |||||
if (status != REDIS_OK) { | |||||
g_error("Failed to disconnect: %s", ac->errstr); | |||||
} else { | |||||
g_printerr("Disconnected...\n"); | |||||
g_main_loop_quit(mainloop); | |||||
} | |||||
} | |||||
static void | |||||
command_cb(redisAsyncContext *ac, | |||||
gpointer r, | |||||
gpointer user_data G_GNUC_UNUSED) | |||||
{ | |||||
redisReply *reply = r; | |||||
if (reply) { | |||||
g_print("REPLY: %s\n", reply->str); | |||||
} | |||||
redisAsyncDisconnect(ac); | |||||
} | |||||
gint | |||||
main (gint argc G_GNUC_UNUSED, | |||||
gchar *argv[] G_GNUC_UNUSED) | |||||
{ | |||||
redisAsyncContext *ac; | |||||
GMainContext *context = NULL; | |||||
GSource *source; | |||||
ac = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (ac->err) { | |||||
g_printerr("%s\n", ac->errstr); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
source = redis_source_new(ac); | |||||
mainloop = g_main_loop_new(context, FALSE); | |||||
g_source_attach(source, context); | |||||
redisAsyncSetConnectCallback(ac, connect_cb); | |||||
redisAsyncSetDisconnectCallback(ac, disconnect_cb); | |||||
redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); | |||||
redisAsyncCommand(ac, command_cb, NULL, "GET key"); | |||||
g_main_loop_run(mainloop); | |||||
return EXIT_SUCCESS; | |||||
} |
@@ -0,0 +1,58 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/ivykis.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
iv_init(); | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
redisIvykisAttach(c); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
iv_main(); | |||||
iv_deinit(); | |||||
return 0; | |||||
} |
@@ -0,0 +1,52 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/libev.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
redisLibevAttach(EV_DEFAULT_ c); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
ev_loop(EV_DEFAULT_ 0); | |||||
return 0; | |||||
} |
@@ -0,0 +1,73 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <hiredis_ssl.h> | |||||
#include <async.h> | |||||
#include <adapters/libevent.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
struct event_base *base = event_base_new(); | |||||
if (argc < 5) { | |||||
fprintf(stderr, | |||||
"Usage: %s <key> <host> <port> <cert> <certKey> [ca]\n", argv[0]); | |||||
exit(1); | |||||
} | |||||
const char *value = argv[1]; | |||||
size_t nvalue = strlen(value); | |||||
const char *hostname = argv[2]; | |||||
int port = atoi(argv[3]); | |||||
const char *cert = argv[4]; | |||||
const char *certKey = argv[5]; | |||||
const char *caCert = argc > 5 ? argv[6] : NULL; | |||||
redisAsyncContext *c = redisAsyncConnect(hostname, port); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
if (redisSecureConnection(&c->c, caCert, cert, certKey, "sni") != REDIS_OK) { | |||||
printf("SSL Error!\n"); | |||||
exit(1); | |||||
} | |||||
redisLibeventAttach(c,base); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
event_base_dispatch(base); | |||||
return 0; | |||||
} |
@@ -0,0 +1,64 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/libevent.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) { | |||||
if (c->errstr) { | |||||
printf("errstr: %s\n", c->errstr); | |||||
} | |||||
return; | |||||
} | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
struct event_base *base = event_base_new(); | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); | |||||
struct timeval tv = {0}; | |||||
tv.tv_sec = 1; | |||||
options.timeout = &tv; | |||||
redisAsyncContext *c = redisAsyncConnectWithOptions(&options); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
redisLibeventAttach(c,base); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
event_base_dispatch(base); | |||||
return 0; | |||||
} |
@@ -0,0 +1,53 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/libuv.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
uv_loop_t* loop = uv_default_loop(); | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
redisLibuvAttach(c,loop); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
uv_run(loop, UV_RUN_DEFAULT); | |||||
return 0; | |||||
} |
@@ -0,0 +1,66 @@ | |||||
// | |||||
// Created by Дмитрий Бахвалов on 13.07.15. | |||||
// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. | |||||
// | |||||
#include <stdio.h> | |||||
#include <hiredis.h> | |||||
#include <async.h> | |||||
#include <adapters/macosx.h> | |||||
void getCallback(redisAsyncContext *c, void *r, void *privdata) { | |||||
redisReply *reply = r; | |||||
if (reply == NULL) return; | |||||
printf("argv[%s]: %s\n", (char*)privdata, reply->str); | |||||
/* Disconnect after receiving the reply to GET */ | |||||
redisAsyncDisconnect(c); | |||||
} | |||||
void connectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
printf("Connected...\n"); | |||||
} | |||||
void disconnectCallback(const redisAsyncContext *c, int status) { | |||||
if (status != REDIS_OK) { | |||||
printf("Error: %s\n", c->errstr); | |||||
return; | |||||
} | |||||
CFRunLoopStop(CFRunLoopGetCurrent()); | |||||
printf("Disconnected...\n"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
signal(SIGPIPE, SIG_IGN); | |||||
CFRunLoopRef loop = CFRunLoopGetCurrent(); | |||||
if( !loop ) { | |||||
printf("Error: Cannot get current run loop\n"); | |||||
return 1; | |||||
} | |||||
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); | |||||
if (c->err) { | |||||
/* Let *c leak for now... */ | |||||
printf("Error: %s\n", c->errstr); | |||||
return 1; | |||||
} | |||||
redisMacOSAttach(c, loop); | |||||
redisAsyncSetConnectCallback(c,connectCallback); | |||||
redisAsyncSetDisconnectCallback(c,disconnectCallback); | |||||
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); | |||||
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); | |||||
CFRunLoopRun(); | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,46 @@ | |||||
#include <iostream> | |||||
using namespace std; | |||||
#include <QCoreApplication> | |||||
#include <QTimer> | |||||
#include "example-qt.h" | |||||
void getCallback(redisAsyncContext *, void * r, void * privdata) { | |||||
redisReply * reply = static_cast<redisReply *>(r); | |||||
ExampleQt * ex = static_cast<ExampleQt *>(privdata); | |||||
if (reply == nullptr || ex == nullptr) return; | |||||
cout << "key: " << reply->str << endl; | |||||
ex->finish(); | |||||
} | |||||
void ExampleQt::run() { | |||||
m_ctx = redisAsyncConnect("localhost", 6379); | |||||
if (m_ctx->err) { | |||||
cerr << "Error: " << m_ctx->errstr << endl; | |||||
redisAsyncFree(m_ctx); | |||||
emit finished(); | |||||
} | |||||
m_adapter.setContext(m_ctx); | |||||
redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); | |||||
redisAsyncCommand(m_ctx, getCallback, this, "GET key"); | |||||
} | |||||
int main (int argc, char **argv) { | |||||
QCoreApplication app(argc, argv); | |||||
ExampleQt example(argv[argc-1]); | |||||
QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit())); | |||||
QTimer::singleShot(0, &example, SLOT(run())); | |||||
return app.exec(); | |||||
} |
@@ -0,0 +1,32 @@ | |||||
#ifndef __HIREDIS_EXAMPLE_QT_H | |||||
#define __HIREDIS_EXAMPLE_QT_H | |||||
#include <adapters/qt.h> | |||||
class ExampleQt : public QObject { | |||||
Q_OBJECT | |||||
public: | |||||
ExampleQt(const char * value, QObject * parent = 0) | |||||
: QObject(parent), m_value(value) {} | |||||
signals: | |||||
void finished(); | |||||
public slots: | |||||
void run(); | |||||
private: | |||||
void finish() { emit finished(); } | |||||
private: | |||||
const char * m_value; | |||||
redisAsyncContext * m_ctx; | |||||
RedisQtAdapter m_adapter; | |||||
friend | |||||
void getCallback(redisAsyncContext *, void *, void *); | |||||
}; | |||||
#endif /* !__HIREDIS_EXAMPLE_QT_H */ |
@@ -0,0 +1,97 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <hiredis.h> | |||||
#include <hiredis_ssl.h> | |||||
int main(int argc, char **argv) { | |||||
unsigned int j; | |||||
redisContext *c; | |||||
redisReply *reply; | |||||
if (argc < 4) { | |||||
printf("Usage: %s <host> <port> <cert> <key> [ca]\n", argv[0]); | |||||
exit(1); | |||||
} | |||||
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; | |||||
int port = atoi(argv[2]); | |||||
const char *cert = argv[3]; | |||||
const char *key = argv[4]; | |||||
const char *ca = argc > 4 ? argv[5] : NULL; | |||||
struct timeval tv = { 1, 500000 }; // 1.5 seconds | |||||
redisOptions options = {0}; | |||||
REDIS_OPTIONS_SET_TCP(&options, hostname, port); | |||||
options.timeout = &tv; | |||||
c = redisConnectWithOptions(&options); | |||||
if (c == NULL || c->err) { | |||||
if (c) { | |||||
printf("Connection error: %s\n", c->errstr); | |||||
redisFree(c); | |||||
} else { | |||||
printf("Connection error: can't allocate redis context\n"); | |||||
} | |||||
exit(1); | |||||
} | |||||
if (redisSecureConnection(c, ca, cert, key, "sni") != REDIS_OK) { | |||||
printf("Couldn't initialize SSL!\n"); | |||||
printf("Error: %s\n", c->errstr); | |||||
redisFree(c); | |||||
exit(1); | |||||
} | |||||
/* PING server */ | |||||
reply = redisCommand(c,"PING"); | |||||
printf("PING: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Set a key */ | |||||
reply = redisCommand(c,"SET %s %s", "foo", "hello world"); | |||||
printf("SET: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Set a key using binary safe API */ | |||||
reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); | |||||
printf("SET (binary API): %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Try a GET and two INCR */ | |||||
reply = redisCommand(c,"GET foo"); | |||||
printf("GET foo: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
reply = redisCommand(c,"INCR counter"); | |||||
printf("INCR counter: %lld\n", reply->integer); | |||||
freeReplyObject(reply); | |||||
/* again ... */ | |||||
reply = redisCommand(c,"INCR counter"); | |||||
printf("INCR counter: %lld\n", reply->integer); | |||||
freeReplyObject(reply); | |||||
/* Create a list of numbers, from 0 to 9 */ | |||||
reply = redisCommand(c,"DEL mylist"); | |||||
freeReplyObject(reply); | |||||
for (j = 0; j < 10; j++) { | |||||
char buf[64]; | |||||
snprintf(buf,64,"%u",j); | |||||
reply = redisCommand(c,"LPUSH mylist element-%s", buf); | |||||
freeReplyObject(reply); | |||||
} | |||||
/* Let's check what we have inside the list */ | |||||
reply = redisCommand(c,"LRANGE mylist 0 -1"); | |||||
if (reply->type == REDIS_REPLY_ARRAY) { | |||||
for (j = 0; j < reply->elements; j++) { | |||||
printf("%u) %s\n", j, reply->element[j]->str); | |||||
} | |||||
} | |||||
freeReplyObject(reply); | |||||
/* Disconnects and frees the context */ | |||||
redisFree(c); | |||||
return 0; | |||||
} |
@@ -0,0 +1,91 @@ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <hiredis.h> | |||||
int main(int argc, char **argv) { | |||||
unsigned int j, isunix = 0; | |||||
redisContext *c; | |||||
redisReply *reply; | |||||
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; | |||||
if (argc > 2) { | |||||
if (*argv[2] == 'u' || *argv[2] == 'U') { | |||||
isunix = 1; | |||||
/* in this case, host is the path to the unix socket */ | |||||
printf("Will connect to unix socket @%s\n", hostname); | |||||
} | |||||
} | |||||
int port = (argc > 2) ? atoi(argv[2]) : 6379; | |||||
struct timeval timeout = { 1, 500000 }; // 1.5 seconds | |||||
if (isunix) { | |||||
c = redisConnectUnixWithTimeout(hostname, timeout); | |||||
} else { | |||||
c = redisConnectWithTimeout(hostname, port, timeout); | |||||
} | |||||
if (c == NULL || c->err) { | |||||
if (c) { | |||||
printf("Connection error: %s\n", c->errstr); | |||||
redisFree(c); | |||||
} else { | |||||
printf("Connection error: can't allocate redis context\n"); | |||||
} | |||||
exit(1); | |||||
} | |||||
/* PING server */ | |||||
reply = redisCommand(c,"PING"); | |||||
printf("PING: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Set a key */ | |||||
reply = redisCommand(c,"SET %s %s", "foo", "hello world"); | |||||
printf("SET: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Set a key using binary safe API */ | |||||
reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); | |||||
printf("SET (binary API): %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
/* Try a GET and two INCR */ | |||||
reply = redisCommand(c,"GET foo"); | |||||
printf("GET foo: %s\n", reply->str); | |||||
freeReplyObject(reply); | |||||
reply = redisCommand(c,"INCR counter"); | |||||
printf("INCR counter: %lld\n", reply->integer); | |||||
freeReplyObject(reply); | |||||
/* again ... */ | |||||
reply = redisCommand(c,"INCR counter"); | |||||
printf("INCR counter: %lld\n", reply->integer); | |||||
freeReplyObject(reply); | |||||
/* Create a list of numbers, from 0 to 9 */ | |||||
reply = redisCommand(c,"DEL mylist"); | |||||
freeReplyObject(reply); | |||||
for (j = 0; j < 10; j++) { | |||||
char buf[64]; | |||||
snprintf(buf,64,"%u",j); | |||||
reply = redisCommand(c,"LPUSH mylist element-%s", buf); | |||||
freeReplyObject(reply); | |||||
} | |||||
/* Let's check what we have inside the list */ | |||||
reply = redisCommand(c,"LRANGE mylist 0 -1"); | |||||
if (reply->type == REDIS_REPLY_ARRAY) { | |||||
for (j = 0; j < reply->elements; j++) { | |||||
printf("%u) %s\n", j, reply->element[j]->str); | |||||
} | |||||
} | |||||
freeReplyObject(reply); | |||||
/* Disconnects and frees the context */ | |||||
redisFree(c); | |||||
return 0; | |||||
} |
@@ -0,0 +1,12 @@ | |||||
#ifndef __HIREDIS_FMACRO_H | |||||
#define __HIREDIS_FMACRO_H | |||||
#define _XOPEN_SOURCE 600 | |||||
#define _POSIX_C_SOURCE 200112L | |||||
#if defined(__APPLE__) && defined(__MACH__) | |||||
/* Enable TCP_KEEPALIVE */ | |||||
#define _DARWIN_C_SOURCE | |||||
#endif | |||||
#endif |
@@ -0,0 +1,298 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* Copyright (c) 2015, Matt Stancliff <matt at genges dot com>, | |||||
* Jan-Erik Rediger <janerik at fnordig dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_H | |||||
#define __HIREDIS_H | |||||
#include "read.h" | |||||
#include <stdarg.h> /* for va_list */ | |||||
#ifndef _MSC_VER | |||||
#include <sys/time.h> /* for struct timeval */ | |||||
#else | |||||
struct timeval; /* forward declaration */ | |||||
#endif | |||||
#include <stdint.h> /* uintXX_t, etc */ | |||||
#include "sds.h" /* for sds */ | |||||
#include "alloc.h" /* for allocation wrappers */ | |||||
#define HIREDIS_MAJOR 0 | |||||
#define HIREDIS_MINOR 14 | |||||
#define HIREDIS_PATCH 0 | |||||
#define HIREDIS_SONAME 0.14 | |||||
/* Connection type can be blocking or non-blocking and is set in the | |||||
* least significant bit of the flags field in redisContext. */ | |||||
#define REDIS_BLOCK 0x1 | |||||
/* Connection may be disconnected before being free'd. The second bit | |||||
* in the flags field is set when the context is connected. */ | |||||
#define REDIS_CONNECTED 0x2 | |||||
/* The async API might try to disconnect cleanly and flush the output | |||||
* buffer and read all subsequent replies before disconnecting. | |||||
* This flag means no new commands can come in and the connection | |||||
* should be terminated once all replies have been read. */ | |||||
#define REDIS_DISCONNECTING 0x4 | |||||
/* Flag specific to the async API which means that the context should be clean | |||||
* up as soon as possible. */ | |||||
#define REDIS_FREEING 0x8 | |||||
/* Flag that is set when an async callback is executed. */ | |||||
#define REDIS_IN_CALLBACK 0x10 | |||||
/* Flag that is set when the async context has one or more subscriptions. */ | |||||
#define REDIS_SUBSCRIBED 0x20 | |||||
/* Flag that is set when monitor mode is active */ | |||||
#define REDIS_MONITORING 0x40 | |||||
/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ | |||||
#define REDIS_REUSEADDR 0x80 | |||||
/** | |||||
* Flag that indicates the user does not want the context to | |||||
* be automatically freed upon error | |||||
*/ | |||||
#define REDIS_NO_AUTO_FREE 0x200 | |||||
#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ | |||||
/* number of times we retry to connect in the case of EADDRNOTAVAIL and | |||||
* SO_REUSEADDR is being used. */ | |||||
#define REDIS_CONNECT_RETRIES 10 | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
/* This is the reply object returned by redisCommand() */ | |||||
typedef struct redisReply { | |||||
int type; /* REDIS_REPLY_* */ | |||||
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ | |||||
double dval; /* The double when type is REDIS_REPLY_DOUBLE */ | |||||
size_t len; /* Length of string */ | |||||
char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING | |||||
and REDIS_REPLY_DOUBLE (in additional to dval). */ | |||||
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ | |||||
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ | |||||
} redisReply; | |||||
redisReader *redisReaderCreate(void); | |||||
/* Function to free the reply objects hiredis returns by default. */ | |||||
void freeReplyObject(void *reply); | |||||
/* Functions to format a command according to the protocol. */ | |||||
int redisvFormatCommand(char **target, const char *format, va_list ap); | |||||
int redisFormatCommand(char **target, const char *format, ...); | |||||
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); | |||||
int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); | |||||
void redisFreeCommand(char *cmd); | |||||
void redisFreeSdsCommand(sds cmd); | |||||
enum redisConnectionType { | |||||
REDIS_CONN_TCP, | |||||
REDIS_CONN_UNIX, | |||||
REDIS_CONN_USERFD | |||||
}; | |||||
struct redisSsl; | |||||
#define REDIS_OPT_NONBLOCK 0x01 | |||||
#define REDIS_OPT_REUSEADDR 0x02 | |||||
/** | |||||
* Don't automatically free the async object on a connection failure, | |||||
* or other implicit conditions. Only free on an explicit call to disconnect() or free() | |||||
*/ | |||||
#define REDIS_OPT_NOAUTOFREE 0x04 | |||||
/* In Unix systems a file descriptor is a regular signed int, with -1 | |||||
* representing an invalid descriptor. In Windows it is a SOCKET | |||||
* (32- or 64-bit unsigned integer depending on the architecture), where | |||||
* all bits set (~0) is INVALID_SOCKET. */ | |||||
#ifndef _WIN32 | |||||
typedef int redisFD; | |||||
#define REDIS_INVALID_FD -1 | |||||
#else | |||||
#ifdef _WIN64 | |||||
typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ | |||||
#else | |||||
typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ | |||||
#endif | |||||
#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ | |||||
#endif | |||||
typedef struct { | |||||
/* | |||||
* the type of connection to use. This also indicates which | |||||
* `endpoint` member field to use | |||||
*/ | |||||
int type; | |||||
/* bit field of REDIS_OPT_xxx */ | |||||
int options; | |||||
/* timeout value. if NULL, no timeout is used */ | |||||
const struct timeval *timeout; | |||||
union { | |||||
/** use this field for tcp/ip connections */ | |||||
struct { | |||||
const char *source_addr; | |||||
const char *ip; | |||||
int port; | |||||
} tcp; | |||||
/** use this field for unix domain sockets */ | |||||
const char *unix_socket; | |||||
/** | |||||
* use this field to have hiredis operate an already-open | |||||
* file descriptor */ | |||||
redisFD fd; | |||||
} endpoint; | |||||
} redisOptions; | |||||
/** | |||||
* Helper macros to initialize options to their specified fields. | |||||
*/ | |||||
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \ | |||||
(opts)->type = REDIS_CONN_TCP; \ | |||||
(opts)->endpoint.tcp.ip = ip_; \ | |||||
(opts)->endpoint.tcp.port = port_; | |||||
#define REDIS_OPTIONS_SET_UNIX(opts, path) \ | |||||
(opts)->type = REDIS_CONN_UNIX; \ | |||||
(opts)->endpoint.unix_socket = path; | |||||
struct redisAsyncContext; | |||||
struct redisContext; | |||||
typedef struct redisContextFuncs { | |||||
void (*free_privdata)(void *); | |||||
void (*async_read)(struct redisAsyncContext *); | |||||
void (*async_write)(struct redisAsyncContext *); | |||||
int (*read)(struct redisContext *, char *, size_t); | |||||
int (*write)(struct redisContext *); | |||||
} redisContextFuncs; | |||||
/* Context for a connection to Redis */ | |||||
typedef struct redisContext { | |||||
const redisContextFuncs *funcs; /* Function table */ | |||||
int err; /* Error flags, 0 when there is no error */ | |||||
char errstr[128]; /* String representation of error when applicable */ | |||||
redisFD fd; | |||||
int flags; | |||||
char *obuf; /* Write buffer */ | |||||
redisReader *reader; /* Protocol reader */ | |||||
enum redisConnectionType connection_type; | |||||
struct timeval *timeout; | |||||
struct { | |||||
char *host; | |||||
char *source_addr; | |||||
int port; | |||||
} tcp; | |||||
struct { | |||||
char *path; | |||||
} unix_sock; | |||||
/* For non-blocking connect */ | |||||
struct sockadr *saddr; | |||||
size_t addrlen; | |||||
/* Additional private data for hiredis addons such as SSL */ | |||||
void *privdata; | |||||
} redisContext; | |||||
redisContext *redisConnectWithOptions(const redisOptions *options); | |||||
redisContext *redisConnect(const char *ip, int port); | |||||
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); | |||||
redisContext *redisConnectNonBlock(const char *ip, int port); | |||||
redisContext *redisConnectBindNonBlock(const char *ip, int port, | |||||
const char *source_addr); | |||||
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, | |||||
const char *source_addr); | |||||
redisContext *redisConnectUnix(const char *path); | |||||
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); | |||||
redisContext *redisConnectUnixNonBlock(const char *path); | |||||
redisContext *redisConnectFd(redisFD fd); | |||||
/** | |||||
* Reconnect the given context using the saved information. | |||||
* | |||||
* This re-uses the exact same connect options as in the initial connection. | |||||
* host, ip (or path), timeout and bind address are reused, | |||||
* flags are used unmodified from the existing context. | |||||
* | |||||
* Returns REDIS_OK on successful connect or REDIS_ERR otherwise. | |||||
*/ | |||||
int redisReconnect(redisContext *c); | |||||
int redisSetTimeout(redisContext *c, const struct timeval tv); | |||||
int redisEnableKeepAlive(redisContext *c); | |||||
void redisFree(redisContext *c); | |||||
redisFD redisFreeKeepFd(redisContext *c); | |||||
int redisBufferRead(redisContext *c); | |||||
int redisBufferWrite(redisContext *c, int *done); | |||||
/* In a blocking context, this function first checks if there are unconsumed | |||||
* replies to return and returns one if so. Otherwise, it flushes the output | |||||
* buffer to the socket and reads until it has a reply. In a non-blocking | |||||
* context, it will return unconsumed replies until there are no more. */ | |||||
int redisGetReply(redisContext *c, void **reply); | |||||
int redisGetReplyFromReader(redisContext *c, void **reply); | |||||
/* Write a formatted command to the output buffer. Use these functions in blocking mode | |||||
* to get a pipeline of commands. */ | |||||
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); | |||||
/* Write a command to the output buffer. Use these functions in blocking mode | |||||
* to get a pipeline of commands. */ | |||||
int redisvAppendCommand(redisContext *c, const char *format, va_list ap); | |||||
int redisAppendCommand(redisContext *c, const char *format, ...); | |||||
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |||||
/* Issue a command to Redis. In a blocking context, it is identical to calling | |||||
* redisAppendCommand, followed by redisGetReply. The function will return | |||||
* NULL if there was an error in performing the request, otherwise it will | |||||
* return the reply. In a non-blocking context, it is identical to calling | |||||
* only redisAppendCommand and will always return NULL. */ | |||||
void *redisvCommand(redisContext *c, const char *format, va_list ap); | |||||
void *redisCommand(redisContext *c, const char *format, ...); | |||||
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
#endif |
@@ -0,0 +1,11 @@ | |||||
prefix=@CMAKE_INSTALL_PREFIX@ | |||||
exec_prefix=${prefix} | |||||
libdir=${exec_prefix}/lib | |||||
includedir=${prefix}/include | |||||
pkgincludedir=${includedir}/hiredis | |||||
Name: hiredis | |||||
Description: Minimalistic C client library for Redis. | |||||
Version: @PROJECT_VERSION@ | |||||
Libs: -L${libdir} -lhiredis | |||||
Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64 |
@@ -0,0 +1,53 @@ | |||||
/* | |||||
* Copyright (c) 2019, Redis Labs | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_SSL_H | |||||
#define __HIREDIS_SSL_H | |||||
/* This is the underlying struct for SSL in ssl.h, which is not included to | |||||
* keep build dependencies short here. | |||||
*/ | |||||
struct ssl_st; | |||||
/** | |||||
* Secure the connection using SSL. This should be done before any command is | |||||
* executed on the connection. | |||||
*/ | |||||
int redisSecureConnection(redisContext *c, const char *capath, const char *certpath, | |||||
const char *keypath, const char *servername); | |||||
/** | |||||
* Initiate SSL/TLS negotiation on a provided context. | |||||
*/ | |||||
int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); | |||||
#endif /* __HIREDIS_SSL_H */ |
@@ -0,0 +1,12 @@ | |||||
prefix=@CMAKE_INSTALL_PREFIX@ | |||||
exec_prefix=${prefix} | |||||
libdir=${exec_prefix}/lib | |||||
includedir=${prefix}/include | |||||
pkgincludedir=${includedir}/hiredis | |||||
Name: hiredis_ssl | |||||
Description: SSL Support for hiredis. | |||||
Version: @PROJECT_VERSION@ | |||||
Requires: hiredis | |||||
Libs: -L${libdir} -lhiredis_ssl | |||||
Libs.private: -lssl -lcrypto |
@@ -0,0 +1,571 @@ | |||||
/* Extracted from anet.c to work properly with Hiredis error reporting. | |||||
* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* Copyright (c) 2015, Matt Stancliff <matt at genges dot com>, | |||||
* Jan-Erik Rediger <janerik at fnordig dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "fmacros.h" | |||||
#include <sys/types.h> | |||||
#include <fcntl.h> | |||||
#include <string.h> | |||||
#include <errno.h> | |||||
#include <stdarg.h> | |||||
#include <stdio.h> | |||||
#include <limits.h> | |||||
#include <stdlib.h> | |||||
#include "net.h" | |||||
#include "sds.h" | |||||
#include "sockcompat.h" | |||||
#include "win32.h" | |||||
/* Defined in hiredis.c */ | |||||
void __redisSetError(redisContext *c, int type, const char *str); | |||||
void redisNetClose(redisContext *c) { | |||||
if (c && c->fd != REDIS_INVALID_FD) { | |||||
close(c->fd); | |||||
c->fd = REDIS_INVALID_FD; | |||||
} | |||||
} | |||||
int redisNetRead(redisContext *c, char *buf, size_t bufcap) { | |||||
int nread = recv(c->fd, buf, bufcap, 0); | |||||
if (nread == -1) { | |||||
if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { | |||||
/* Try again later */ | |||||
return 0; | |||||
} else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) { | |||||
/* especially in windows */ | |||||
__redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout"); | |||||
return -1; | |||||
} else { | |||||
__redisSetError(c, REDIS_ERR_IO, NULL); | |||||
return -1; | |||||
} | |||||
} else if (nread == 0) { | |||||
__redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); | |||||
return -1; | |||||
} else { | |||||
return nread; | |||||
} | |||||
} | |||||
int redisNetWrite(redisContext *c) { | |||||
int nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0); | |||||
if (nwritten < 0) { | |||||
if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { | |||||
/* Try again later */ | |||||
} else { | |||||
__redisSetError(c, REDIS_ERR_IO, NULL); | |||||
return -1; | |||||
} | |||||
} | |||||
return nwritten; | |||||
} | |||||
static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) { | |||||
int errorno = errno; /* snprintf() may change errno */ | |||||
char buf[128] = { 0 }; | |||||
size_t len = 0; | |||||
if (prefix != NULL) | |||||
len = snprintf(buf,sizeof(buf),"%s: ",prefix); | |||||
strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len); | |||||
__redisSetError(c,type,buf); | |||||
} | |||||
static int redisSetReuseAddr(redisContext *c) { | |||||
int on = 1; | |||||
if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
static int redisCreateSocket(redisContext *c, int type) { | |||||
redisFD s; | |||||
if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); | |||||
return REDIS_ERR; | |||||
} | |||||
c->fd = s; | |||||
if (type == AF_INET) { | |||||
if (redisSetReuseAddr(c) == REDIS_ERR) { | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
static int redisSetBlocking(redisContext *c, int blocking) { | |||||
#ifndef _WIN32 | |||||
int flags; | |||||
/* Set the socket nonblocking. | |||||
* Note that fcntl(2) for F_GETFL and F_SETFL can't be | |||||
* interrupted by a signal. */ | |||||
if ((flags = fcntl(c->fd, F_GETFL)) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
if (blocking) | |||||
flags &= ~O_NONBLOCK; | |||||
else | |||||
flags |= O_NONBLOCK; | |||||
if (fcntl(c->fd, F_SETFL, flags) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
#else | |||||
u_long mode = blocking ? 0 : 1; | |||||
if (ioctl(c->fd, FIONBIO, &mode) == -1) { | |||||
__redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)"); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
#endif /* _WIN32 */ | |||||
return REDIS_OK; | |||||
} | |||||
int redisKeepAlive(redisContext *c, int interval) { | |||||
int val = 1; | |||||
redisFD fd = c->fd; | |||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ | |||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); | |||||
return REDIS_ERR; | |||||
} | |||||
val = interval; | |||||
#if defined(__APPLE__) && defined(__MACH__) | |||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { | |||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); | |||||
return REDIS_ERR; | |||||
} | |||||
#else | |||||
#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) | |||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { | |||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); | |||||
return REDIS_ERR; | |||||
} | |||||
val = interval/3; | |||||
if (val == 0) val = 1; | |||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { | |||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); | |||||
return REDIS_ERR; | |||||
} | |||||
val = 3; | |||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { | |||||
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); | |||||
return REDIS_ERR; | |||||
} | |||||
#endif | |||||
#endif | |||||
return REDIS_OK; | |||||
} | |||||
static int redisSetTcpNoDelay(redisContext *c) { | |||||
int yes = 1; | |||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
#define __MAX_MSEC (((LONG_MAX) - 999) / 1000) | |||||
static int redisContextTimeoutMsec(redisContext *c, long *result) | |||||
{ | |||||
const struct timeval *timeout = c->timeout; | |||||
long msec = -1; | |||||
/* Only use timeout when not NULL. */ | |||||
if (timeout != NULL) { | |||||
if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { | |||||
*result = msec; | |||||
return REDIS_ERR; | |||||
} | |||||
msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); | |||||
if (msec < 0 || msec > INT_MAX) { | |||||
msec = INT_MAX; | |||||
} | |||||
} | |||||
*result = msec; | |||||
return REDIS_OK; | |||||
} | |||||
static int redisContextWaitReady(redisContext *c, long msec) { | |||||
struct pollfd wfd[1]; | |||||
wfd[0].fd = c->fd; | |||||
wfd[0].events = POLLOUT; | |||||
if (errno == EINPROGRESS) { | |||||
int res; | |||||
if ((res = poll(wfd, 1, msec)) == -1) { | |||||
__redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} else if (res == 0) { | |||||
errno = ETIMEDOUT; | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { | |||||
redisCheckSocketError(c); | |||||
return REDIS_ERR; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); | |||||
redisNetClose(c); | |||||
return REDIS_ERR; | |||||
} | |||||
int redisCheckConnectDone(redisContext *c, int *completed) { | |||||
int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); | |||||
if (rc == 0) { | |||||
*completed = 1; | |||||
return REDIS_OK; | |||||
} | |||||
switch (errno) { | |||||
case EISCONN: | |||||
*completed = 1; | |||||
return REDIS_OK; | |||||
case EALREADY: | |||||
case EINPROGRESS: | |||||
case EWOULDBLOCK: | |||||
*completed = 0; | |||||
return REDIS_OK; | |||||
default: | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
int redisCheckSocketError(redisContext *c) { | |||||
int err = 0, errno_saved = errno; | |||||
socklen_t errlen = sizeof(err); | |||||
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); | |||||
return REDIS_ERR; | |||||
} | |||||
if (err == 0) { | |||||
err = errno_saved; | |||||
} | |||||
if (err) { | |||||
errno = err; | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); | |||||
return REDIS_ERR; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
int redisContextSetTimeout(redisContext *c, const struct timeval tv) { | |||||
const void *to_ptr = &tv; | |||||
size_t to_sz = sizeof(tv); | |||||
#ifdef _WIN32 | |||||
DWORD timeout_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; | |||||
to_ptr = &timeout_msec; | |||||
to_sz = sizeof(timeout_msec); | |||||
#endif | |||||
if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); | |||||
return REDIS_ERR; | |||||
} | |||||
if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) { | |||||
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); | |||||
return REDIS_ERR; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, | |||||
const struct timeval *timeout, | |||||
const char *source_addr) { | |||||
redisFD s; | |||||
int rv, n; | |||||
char _port[6]; /* strlen("65535"); */ | |||||
struct addrinfo hints, *servinfo, *bservinfo, *p, *b; | |||||
int blocking = (c->flags & REDIS_BLOCK); | |||||
int reuseaddr = (c->flags & REDIS_REUSEADDR); | |||||
int reuses = 0; | |||||
long timeout_msec = -1; | |||||
servinfo = NULL; | |||||
c->connection_type = REDIS_CONN_TCP; | |||||
c->tcp.port = port; | |||||
/* We need to take possession of the passed parameters | |||||
* to make them reusable for a reconnect. | |||||
* We also carefully check we don't free data we already own, | |||||
* as in the case of the reconnect method. | |||||
* | |||||
* This is a bit ugly, but atleast it works and doesn't leak memory. | |||||
**/ | |||||
if (c->tcp.host != addr) { | |||||
free(c->tcp.host); | |||||
c->tcp.host = hi_strdup(addr); | |||||
} | |||||
if (timeout) { | |||||
if (c->timeout != timeout) { | |||||
if (c->timeout == NULL) | |||||
c->timeout = hi_malloc(sizeof(struct timeval)); | |||||
memcpy(c->timeout, timeout, sizeof(struct timeval)); | |||||
} | |||||
} else { | |||||
free(c->timeout); | |||||
c->timeout = NULL; | |||||
} | |||||
if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { | |||||
__redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); | |||||
goto error; | |||||
} | |||||
if (source_addr == NULL) { | |||||
free(c->tcp.source_addr); | |||||
c->tcp.source_addr = NULL; | |||||
} else if (c->tcp.source_addr != source_addr) { | |||||
free(c->tcp.source_addr); | |||||
c->tcp.source_addr = hi_strdup(source_addr); | |||||
} | |||||
snprintf(_port, 6, "%d", port); | |||||
memset(&hints,0,sizeof(hints)); | |||||
hints.ai_family = AF_INET; | |||||
hints.ai_socktype = SOCK_STREAM; | |||||
/* Try with IPv6 if no IPv4 address was found. We do it in this order since | |||||
* in a Redis client you can't afford to test if you have IPv6 connectivity | |||||
* as this would add latency to every connect. Otherwise a more sensible | |||||
* route could be: Use IPv6 if both addresses are available and there is IPv6 | |||||
* connectivity. */ | |||||
if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { | |||||
hints.ai_family = AF_INET6; | |||||
if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { | |||||
__redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
for (p = servinfo; p != NULL; p = p->ai_next) { | |||||
addrretry: | |||||
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD) | |||||
continue; | |||||
c->fd = s; | |||||
if (redisSetBlocking(c,0) != REDIS_OK) | |||||
goto error; | |||||
if (c->tcp.source_addr) { | |||||
int bound = 0; | |||||
/* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ | |||||
if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { | |||||
char buf[128]; | |||||
snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); | |||||
__redisSetError(c,REDIS_ERR_OTHER,buf); | |||||
goto error; | |||||
} | |||||
if (reuseaddr) { | |||||
n = 1; | |||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, | |||||
sizeof(n)) < 0) { | |||||
freeaddrinfo(bservinfo); | |||||
goto error; | |||||
} | |||||
} | |||||
for (b = bservinfo; b != NULL; b = b->ai_next) { | |||||
if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { | |||||
bound = 1; | |||||
break; | |||||
} | |||||
} | |||||
freeaddrinfo(bservinfo); | |||||
if (!bound) { | |||||
char buf[128]; | |||||
snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); | |||||
__redisSetError(c,REDIS_ERR_OTHER,buf); | |||||
goto error; | |||||
} | |||||
} | |||||
/* For repeat connection */ | |||||
free(c->saddr); | |||||
c->saddr = hi_malloc(p->ai_addrlen); | |||||
memcpy(c->saddr, p->ai_addr, p->ai_addrlen); | |||||
c->addrlen = p->ai_addrlen; | |||||
if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { | |||||
if (errno == EHOSTUNREACH) { | |||||
redisNetClose(c); | |||||
continue; | |||||
} else if (errno == EINPROGRESS) { | |||||
if (blocking) { | |||||
goto wait_for_ready; | |||||
} | |||||
/* This is ok. | |||||
* Note that even when it's in blocking mode, we unset blocking | |||||
* for `connect()` | |||||
*/ | |||||
} else if (errno == EADDRNOTAVAIL && reuseaddr) { | |||||
if (++reuses >= REDIS_CONNECT_RETRIES) { | |||||
goto error; | |||||
} else { | |||||
redisNetClose(c); | |||||
goto addrretry; | |||||
} | |||||
} else { | |||||
wait_for_ready: | |||||
if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) | |||||
goto error; | |||||
} | |||||
} | |||||
if (blocking && redisSetBlocking(c,1) != REDIS_OK) | |||||
goto error; | |||||
if (redisSetTcpNoDelay(c) != REDIS_OK) | |||||
goto error; | |||||
c->flags |= REDIS_CONNECTED; | |||||
rv = REDIS_OK; | |||||
goto end; | |||||
} | |||||
if (p == NULL) { | |||||
char buf[128]; | |||||
snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); | |||||
__redisSetError(c,REDIS_ERR_OTHER,buf); | |||||
goto error; | |||||
} | |||||
error: | |||||
rv = REDIS_ERR; | |||||
end: | |||||
if(servinfo) { | |||||
freeaddrinfo(servinfo); | |||||
} | |||||
return rv; // Need to return REDIS_OK if alright | |||||
} | |||||
int redisContextConnectTcp(redisContext *c, const char *addr, int port, | |||||
const struct timeval *timeout) { | |||||
return _redisContextConnectTcp(c, addr, port, timeout, NULL); | |||||
} | |||||
int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, | |||||
const struct timeval *timeout, | |||||
const char *source_addr) { | |||||
return _redisContextConnectTcp(c, addr, port, timeout, source_addr); | |||||
} | |||||
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { | |||||
#ifndef _WIN32 | |||||
int blocking = (c->flags & REDIS_BLOCK); | |||||
struct sockaddr_un *sa; | |||||
long timeout_msec = -1; | |||||
if (redisCreateSocket(c,AF_UNIX) < 0) | |||||
return REDIS_ERR; | |||||
if (redisSetBlocking(c,0) != REDIS_OK) | |||||
return REDIS_ERR; | |||||
c->connection_type = REDIS_CONN_UNIX; | |||||
if (c->unix_sock.path != path) | |||||
c->unix_sock.path = hi_strdup(path); | |||||
if (timeout) { | |||||
if (c->timeout != timeout) { | |||||
if (c->timeout == NULL) | |||||
c->timeout = hi_malloc(sizeof(struct timeval)); | |||||
memcpy(c->timeout, timeout, sizeof(struct timeval)); | |||||
} | |||||
} else { | |||||
free(c->timeout); | |||||
c->timeout = NULL; | |||||
} | |||||
if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) | |||||
return REDIS_ERR; | |||||
sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un))); | |||||
c->addrlen = sizeof(struct sockaddr_un); | |||||
sa->sun_family = AF_UNIX; | |||||
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1); | |||||
if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) { | |||||
if (errno == EINPROGRESS && !blocking) { | |||||
/* This is ok. */ | |||||
} else { | |||||
if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
/* Reset socket to be blocking after connect(2). */ | |||||
if (blocking && redisSetBlocking(c,1) != REDIS_OK) | |||||
return REDIS_ERR; | |||||
c->flags |= REDIS_CONNECTED; | |||||
return REDIS_OK; | |||||
#else | |||||
/* We currently do not support Unix sockets for Windows. */ | |||||
/* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */ | |||||
errno = EPROTONOSUPPORT; | |||||
return REDIS_ERR; | |||||
#endif /* _WIN32 */ | |||||
} |
@@ -0,0 +1,54 @@ | |||||
/* Extracted from anet.c to work properly with Hiredis error reporting. | |||||
* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* Copyright (c) 2015, Matt Stancliff <matt at genges dot com>, | |||||
* Jan-Erik Rediger <janerik at fnordig dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __NET_H | |||||
#define __NET_H | |||||
#include "hiredis.h" | |||||
void redisNetClose(redisContext *c); | |||||
int redisNetRead(redisContext *c, char *buf, size_t bufcap); | |||||
int redisNetWrite(redisContext *c); | |||||
int redisCheckSocketError(redisContext *c); | |||||
int redisContextSetTimeout(redisContext *c, const struct timeval tv); | |||||
int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); | |||||
int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, | |||||
const struct timeval *timeout, | |||||
const char *source_addr); | |||||
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); | |||||
int redisKeepAlive(redisContext *c, int interval); | |||||
int redisCheckConnectDone(redisContext *c, int *completed); | |||||
#endif |
@@ -0,0 +1,669 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "fmacros.h" | |||||
#include <string.h> | |||||
#include <stdlib.h> | |||||
#ifndef _MSC_VER | |||||
#include <unistd.h> | |||||
#include <strings.h> | |||||
#endif | |||||
#include <assert.h> | |||||
#include <errno.h> | |||||
#include <ctype.h> | |||||
#include <limits.h> | |||||
#include <math.h> | |||||
#include "read.h" | |||||
#include "sds.h" | |||||
#include "win32.h" | |||||
static void __redisReaderSetError(redisReader *r, int type, const char *str) { | |||||
size_t len; | |||||
if (r->reply != NULL && r->fn && r->fn->freeObject) { | |||||
r->fn->freeObject(r->reply); | |||||
r->reply = NULL; | |||||
} | |||||
/* Clear input buffer on errors. */ | |||||
sdsfree(r->buf); | |||||
r->buf = NULL; | |||||
r->pos = r->len = 0; | |||||
/* Reset task stack. */ | |||||
r->ridx = -1; | |||||
/* Set error. */ | |||||
r->err = type; | |||||
len = strlen(str); | |||||
len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1); | |||||
memcpy(r->errstr,str,len); | |||||
r->errstr[len] = '\0'; | |||||
} | |||||
static size_t chrtos(char *buf, size_t size, char byte) { | |||||
size_t len = 0; | |||||
switch(byte) { | |||||
case '\\': | |||||
case '"': | |||||
len = snprintf(buf,size,"\"\\%c\"",byte); | |||||
break; | |||||
case '\n': len = snprintf(buf,size,"\"\\n\""); break; | |||||
case '\r': len = snprintf(buf,size,"\"\\r\""); break; | |||||
case '\t': len = snprintf(buf,size,"\"\\t\""); break; | |||||
case '\a': len = snprintf(buf,size,"\"\\a\""); break; | |||||
case '\b': len = snprintf(buf,size,"\"\\b\""); break; | |||||
default: | |||||
if (isprint(byte)) | |||||
len = snprintf(buf,size,"\"%c\"",byte); | |||||
else | |||||
len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte); | |||||
break; | |||||
} | |||||
return len; | |||||
} | |||||
static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) { | |||||
char cbuf[8], sbuf[128]; | |||||
chrtos(cbuf,sizeof(cbuf),byte); | |||||
snprintf(sbuf,sizeof(sbuf), | |||||
"Protocol error, got %s as reply type byte", cbuf); | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf); | |||||
} | |||||
static void __redisReaderSetErrorOOM(redisReader *r) { | |||||
__redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory"); | |||||
} | |||||
static char *readBytes(redisReader *r, unsigned int bytes) { | |||||
char *p; | |||||
if (r->len-r->pos >= bytes) { | |||||
p = r->buf+r->pos; | |||||
r->pos += bytes; | |||||
return p; | |||||
} | |||||
return NULL; | |||||
} | |||||
/* Find pointer to \r\n. */ | |||||
static char *seekNewline(char *s, size_t len) { | |||||
int pos = 0; | |||||
int _len = len-1; | |||||
/* Position should be < len-1 because the character at "pos" should be | |||||
* followed by a \n. Note that strchr cannot be used because it doesn't | |||||
* allow to search a limited length and the buffer that is being searched | |||||
* might not have a trailing NULL character. */ | |||||
while (pos < _len) { | |||||
while(pos < _len && s[pos] != '\r') pos++; | |||||
if (pos==_len) { | |||||
/* Not found. */ | |||||
return NULL; | |||||
} else { | |||||
if (s[pos+1] == '\n') { | |||||
/* Found. */ | |||||
return s+pos; | |||||
} else { | |||||
/* Continue searching. */ | |||||
pos++; | |||||
} | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
/* Convert a string into a long long. Returns REDIS_OK if the string could be | |||||
* parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value | |||||
* will be set to the parsed value when appropriate. | |||||
* | |||||
* Note that this function demands that the string strictly represents | |||||
* a long long: no spaces or other characters before or after the string | |||||
* representing the number are accepted, nor zeroes at the start if not | |||||
* for the string "0" representing the zero number. | |||||
* | |||||
* Because of its strictness, it is safe to use this function to check if | |||||
* you can convert a string into a long long, and obtain back the string | |||||
* from the number without any loss in the string representation. */ | |||||
static int string2ll(const char *s, size_t slen, long long *value) { | |||||
const char *p = s; | |||||
size_t plen = 0; | |||||
int negative = 0; | |||||
unsigned long long v; | |||||
if (plen == slen) | |||||
return REDIS_ERR; | |||||
/* Special case: first and only digit is 0. */ | |||||
if (slen == 1 && p[0] == '0') { | |||||
if (value != NULL) *value = 0; | |||||
return REDIS_OK; | |||||
} | |||||
if (p[0] == '-') { | |||||
negative = 1; | |||||
p++; plen++; | |||||
/* Abort on only a negative sign. */ | |||||
if (plen == slen) | |||||
return REDIS_ERR; | |||||
} | |||||
/* First digit should be 1-9, otherwise the string should just be 0. */ | |||||
if (p[0] >= '1' && p[0] <= '9') { | |||||
v = p[0]-'0'; | |||||
p++; plen++; | |||||
} else if (p[0] == '0' && slen == 1) { | |||||
*value = 0; | |||||
return REDIS_OK; | |||||
} else { | |||||
return REDIS_ERR; | |||||
} | |||||
while (plen < slen && p[0] >= '0' && p[0] <= '9') { | |||||
if (v > (ULLONG_MAX / 10)) /* Overflow. */ | |||||
return REDIS_ERR; | |||||
v *= 10; | |||||
if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ | |||||
return REDIS_ERR; | |||||
v += p[0]-'0'; | |||||
p++; plen++; | |||||
} | |||||
/* Return if not all bytes were used. */ | |||||
if (plen < slen) | |||||
return REDIS_ERR; | |||||
if (negative) { | |||||
if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ | |||||
return REDIS_ERR; | |||||
if (value != NULL) *value = -v; | |||||
} else { | |||||
if (v > LLONG_MAX) /* Overflow. */ | |||||
return REDIS_ERR; | |||||
if (value != NULL) *value = v; | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
static char *readLine(redisReader *r, int *_len) { | |||||
char *p, *s; | |||||
int len; | |||||
p = r->buf+r->pos; | |||||
s = seekNewline(p,(r->len-r->pos)); | |||||
if (s != NULL) { | |||||
len = s-(r->buf+r->pos); | |||||
r->pos += len+2; /* skip \r\n */ | |||||
if (_len) *_len = len; | |||||
return p; | |||||
} | |||||
return NULL; | |||||
} | |||||
static void moveToNextTask(redisReader *r) { | |||||
redisReadTask *cur, *prv; | |||||
while (r->ridx >= 0) { | |||||
/* Return a.s.a.p. when the stack is now empty. */ | |||||
if (r->ridx == 0) { | |||||
r->ridx--; | |||||
return; | |||||
} | |||||
cur = &(r->rstack[r->ridx]); | |||||
prv = &(r->rstack[r->ridx-1]); | |||||
assert(prv->type == REDIS_REPLY_ARRAY || | |||||
prv->type == REDIS_REPLY_MAP || | |||||
prv->type == REDIS_REPLY_SET); | |||||
if (cur->idx == prv->elements-1) { | |||||
r->ridx--; | |||||
} else { | |||||
/* Reset the type because the next item can be anything */ | |||||
assert(cur->idx < prv->elements); | |||||
cur->type = -1; | |||||
cur->elements = -1; | |||||
cur->idx++; | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
static int processLineItem(redisReader *r) { | |||||
redisReadTask *cur = &(r->rstack[r->ridx]); | |||||
void *obj; | |||||
char *p; | |||||
int len; | |||||
if ((p = readLine(r,&len)) != NULL) { | |||||
if (cur->type == REDIS_REPLY_INTEGER) { | |||||
if (r->fn && r->fn->createInteger) { | |||||
long long v; | |||||
if (string2ll(p, len, &v) == REDIS_ERR) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Bad integer value"); | |||||
return REDIS_ERR; | |||||
} | |||||
obj = r->fn->createInteger(cur,v); | |||||
} else { | |||||
obj = (void*)REDIS_REPLY_INTEGER; | |||||
} | |||||
} else if (cur->type == REDIS_REPLY_DOUBLE) { | |||||
if (r->fn && r->fn->createDouble) { | |||||
char buf[326], *eptr; | |||||
double d; | |||||
if ((size_t)len >= sizeof(buf)) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Double value is too large"); | |||||
return REDIS_ERR; | |||||
} | |||||
memcpy(buf,p,len); | |||||
buf[len] = '\0'; | |||||
if (strcasecmp(buf,",inf") == 0) { | |||||
d = INFINITY; /* Positive infinite. */ | |||||
} else if (strcasecmp(buf,",-inf") == 0) { | |||||
d = -INFINITY; /* Negative infinite. */ | |||||
} else { | |||||
d = strtod((char*)buf,&eptr); | |||||
if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Bad double value"); | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
obj = r->fn->createDouble(cur,d,buf,len); | |||||
} else { | |||||
obj = (void*)REDIS_REPLY_DOUBLE; | |||||
} | |||||
} else if (cur->type == REDIS_REPLY_NIL) { | |||||
if (r->fn && r->fn->createNil) | |||||
obj = r->fn->createNil(cur); | |||||
else | |||||
obj = (void*)REDIS_REPLY_NIL; | |||||
} else if (cur->type == REDIS_REPLY_BOOL) { | |||||
int bval = p[0] == 't' || p[0] == 'T'; | |||||
if (r->fn && r->fn->createBool) | |||||
obj = r->fn->createBool(cur,bval); | |||||
else | |||||
obj = (void*)REDIS_REPLY_BOOL; | |||||
} else { | |||||
/* Type will be error or status. */ | |||||
if (r->fn && r->fn->createString) | |||||
obj = r->fn->createString(cur,p,len); | |||||
else | |||||
obj = (void*)(size_t)(cur->type); | |||||
} | |||||
if (obj == NULL) { | |||||
__redisReaderSetErrorOOM(r); | |||||
return REDIS_ERR; | |||||
} | |||||
/* Set reply if this is the root object. */ | |||||
if (r->ridx == 0) r->reply = obj; | |||||
moveToNextTask(r); | |||||
return REDIS_OK; | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
static int processBulkItem(redisReader *r) { | |||||
redisReadTask *cur = &(r->rstack[r->ridx]); | |||||
void *obj = NULL; | |||||
char *p, *s; | |||||
long long len; | |||||
unsigned long bytelen; | |||||
int success = 0; | |||||
p = r->buf+r->pos; | |||||
s = seekNewline(p,r->len-r->pos); | |||||
if (s != NULL) { | |||||
p = r->buf+r->pos; | |||||
bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ | |||||
if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Bad bulk string length"); | |||||
return REDIS_ERR; | |||||
} | |||||
if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Bulk string length out of range"); | |||||
return REDIS_ERR; | |||||
} | |||||
if (len == -1) { | |||||
/* The nil object can always be created. */ | |||||
if (r->fn && r->fn->createNil) | |||||
obj = r->fn->createNil(cur); | |||||
else | |||||
obj = (void*)REDIS_REPLY_NIL; | |||||
success = 1; | |||||
} else { | |||||
/* Only continue when the buffer contains the entire bulk item. */ | |||||
bytelen += len+2; /* include \r\n */ | |||||
if (r->pos+bytelen <= r->len) { | |||||
if (r->fn && r->fn->createString) | |||||
obj = r->fn->createString(cur,s+2,len); | |||||
else | |||||
obj = (void*)REDIS_REPLY_STRING; | |||||
success = 1; | |||||
} | |||||
} | |||||
/* Proceed when obj was created. */ | |||||
if (success) { | |||||
if (obj == NULL) { | |||||
__redisReaderSetErrorOOM(r); | |||||
return REDIS_ERR; | |||||
} | |||||
r->pos += bytelen; | |||||
/* Set reply if this is the root object. */ | |||||
if (r->ridx == 0) r->reply = obj; | |||||
moveToNextTask(r); | |||||
return REDIS_OK; | |||||
} | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
/* Process the array, map and set types. */ | |||||
static int processAggregateItem(redisReader *r) { | |||||
redisReadTask *cur = &(r->rstack[r->ridx]); | |||||
void *obj; | |||||
char *p; | |||||
long long elements; | |||||
int root = 0, len; | |||||
/* Set error for nested multi bulks with depth > 7 */ | |||||
if (r->ridx == 8) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"No support for nested multi bulk replies with depth > 7"); | |||||
return REDIS_ERR; | |||||
} | |||||
if ((p = readLine(r,&len)) != NULL) { | |||||
if (string2ll(p, len, &elements) == REDIS_ERR) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Bad multi-bulk length"); | |||||
return REDIS_ERR; | |||||
} | |||||
root = (r->ridx == 0); | |||||
if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX)) { | |||||
__redisReaderSetError(r,REDIS_ERR_PROTOCOL, | |||||
"Multi-bulk length out of range"); | |||||
return REDIS_ERR; | |||||
} | |||||
if (elements == -1) { | |||||
if (r->fn && r->fn->createNil) | |||||
obj = r->fn->createNil(cur); | |||||
else | |||||
obj = (void*)REDIS_REPLY_NIL; | |||||
if (obj == NULL) { | |||||
__redisReaderSetErrorOOM(r); | |||||
return REDIS_ERR; | |||||
} | |||||
moveToNextTask(r); | |||||
} else { | |||||
if (cur->type == REDIS_REPLY_MAP) elements *= 2; | |||||
if (r->fn && r->fn->createArray) | |||||
obj = r->fn->createArray(cur,elements); | |||||
else | |||||
obj = (void*)(long)cur->type; | |||||
if (obj == NULL) { | |||||
__redisReaderSetErrorOOM(r); | |||||
return REDIS_ERR; | |||||
} | |||||
/* Modify task stack when there are more than 0 elements. */ | |||||
if (elements > 0) { | |||||
cur->elements = elements; | |||||
cur->obj = obj; | |||||
r->ridx++; | |||||
r->rstack[r->ridx].type = -1; | |||||
r->rstack[r->ridx].elements = -1; | |||||
r->rstack[r->ridx].idx = 0; | |||||
r->rstack[r->ridx].obj = NULL; | |||||
r->rstack[r->ridx].parent = cur; | |||||
r->rstack[r->ridx].privdata = r->privdata; | |||||
} else { | |||||
moveToNextTask(r); | |||||
} | |||||
} | |||||
/* Set reply if this is the root object. */ | |||||
if (root) r->reply = obj; | |||||
return REDIS_OK; | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
static int processItem(redisReader *r) { | |||||
redisReadTask *cur = &(r->rstack[r->ridx]); | |||||
char *p; | |||||
/* check if we need to read type */ | |||||
if (cur->type < 0) { | |||||
if ((p = readBytes(r,1)) != NULL) { | |||||
switch (p[0]) { | |||||
case '-': | |||||
cur->type = REDIS_REPLY_ERROR; | |||||
break; | |||||
case '+': | |||||
cur->type = REDIS_REPLY_STATUS; | |||||
break; | |||||
case ':': | |||||
cur->type = REDIS_REPLY_INTEGER; | |||||
break; | |||||
case ',': | |||||
cur->type = REDIS_REPLY_DOUBLE; | |||||
break; | |||||
case '_': | |||||
cur->type = REDIS_REPLY_NIL; | |||||
break; | |||||
case '$': | |||||
cur->type = REDIS_REPLY_STRING; | |||||
break; | |||||
case '*': | |||||
cur->type = REDIS_REPLY_ARRAY; | |||||
break; | |||||
case '%': | |||||
cur->type = REDIS_REPLY_MAP; | |||||
break; | |||||
case '~': | |||||
cur->type = REDIS_REPLY_SET; | |||||
break; | |||||
case '#': | |||||
cur->type = REDIS_REPLY_BOOL; | |||||
break; | |||||
default: | |||||
__redisReaderSetErrorProtocolByte(r,*p); | |||||
return REDIS_ERR; | |||||
} | |||||
} else { | |||||
/* could not consume 1 byte */ | |||||
return REDIS_ERR; | |||||
} | |||||
} | |||||
/* process typed item */ | |||||
switch(cur->type) { | |||||
case REDIS_REPLY_ERROR: | |||||
case REDIS_REPLY_STATUS: | |||||
case REDIS_REPLY_INTEGER: | |||||
case REDIS_REPLY_DOUBLE: | |||||
case REDIS_REPLY_NIL: | |||||
case REDIS_REPLY_BOOL: | |||||
return processLineItem(r); | |||||
case REDIS_REPLY_STRING: | |||||
return processBulkItem(r); | |||||
case REDIS_REPLY_ARRAY: | |||||
case REDIS_REPLY_MAP: | |||||
case REDIS_REPLY_SET: | |||||
return processAggregateItem(r); | |||||
default: | |||||
assert(NULL); | |||||
return REDIS_ERR; /* Avoid warning. */ | |||||
} | |||||
} | |||||
redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { | |||||
redisReader *r; | |||||
r = calloc(1,sizeof(redisReader)); | |||||
if (r == NULL) | |||||
return NULL; | |||||
r->fn = fn; | |||||
r->buf = sdsempty(); | |||||
r->maxbuf = REDIS_READER_MAX_BUF; | |||||
if (r->buf == NULL) { | |||||
free(r); | |||||
return NULL; | |||||
} | |||||
r->ridx = -1; | |||||
return r; | |||||
} | |||||
void redisReaderFree(redisReader *r) { | |||||
if (r == NULL) | |||||
return; | |||||
if (r->reply != NULL && r->fn && r->fn->freeObject) | |||||
r->fn->freeObject(r->reply); | |||||
sdsfree(r->buf); | |||||
free(r); | |||||
} | |||||
int redisReaderFeed(redisReader *r, const char *buf, size_t len) { | |||||
sds newbuf; | |||||
/* Return early when this reader is in an erroneous state. */ | |||||
if (r->err) | |||||
return REDIS_ERR; | |||||
/* Copy the provided buffer. */ | |||||
if (buf != NULL && len >= 1) { | |||||
/* Destroy internal buffer when it is empty and is quite large. */ | |||||
if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) { | |||||
sdsfree(r->buf); | |||||
r->buf = sdsempty(); | |||||
r->pos = 0; | |||||
/* r->buf should not be NULL since we just free'd a larger one. */ | |||||
assert(r->buf != NULL); | |||||
} | |||||
newbuf = sdscatlen(r->buf,buf,len); | |||||
if (newbuf == NULL) { | |||||
__redisReaderSetErrorOOM(r); | |||||
return REDIS_ERR; | |||||
} | |||||
r->buf = newbuf; | |||||
r->len = sdslen(r->buf); | |||||
} | |||||
return REDIS_OK; | |||||
} | |||||
int redisReaderGetReply(redisReader *r, void **reply) { | |||||
/* Default target pointer to NULL. */ | |||||
if (reply != NULL) | |||||
*reply = NULL; | |||||
/* Return early when this reader is in an erroneous state. */ | |||||
if (r->err) | |||||
return REDIS_ERR; | |||||
/* When the buffer is empty, there will never be a reply. */ | |||||
if (r->len == 0) | |||||
return REDIS_OK; | |||||
/* Set first item to process when the stack is empty. */ | |||||
if (r->ridx == -1) { | |||||
r->rstack[0].type = -1; | |||||
r->rstack[0].elements = -1; | |||||
r->rstack[0].idx = -1; | |||||
r->rstack[0].obj = NULL; | |||||
r->rstack[0].parent = NULL; | |||||
r->rstack[0].privdata = r->privdata; | |||||
r->ridx = 0; | |||||
} | |||||
/* Process items in reply. */ | |||||
while (r->ridx >= 0) | |||||
if (processItem(r) != REDIS_OK) | |||||
break; | |||||
/* Return ASAP when an error occurred. */ | |||||
if (r->err) | |||||
return REDIS_ERR; | |||||
/* Discard part of the buffer when we've consumed at least 1k, to avoid | |||||
* doing unnecessary calls to memmove() in sds.c. */ | |||||
if (r->pos >= 1024) { | |||||
sdsrange(r->buf,r->pos,-1); | |||||
r->pos = 0; | |||||
r->len = sdslen(r->buf); | |||||
} | |||||
/* Emit a reply when there is one. */ | |||||
if (r->ridx == -1) { | |||||
if (reply != NULL) { | |||||
*reply = r->reply; | |||||
} else if (r->reply != NULL && r->fn && r->fn->freeObject) { | |||||
r->fn->freeObject(r->reply); | |||||
} | |||||
r->reply = NULL; | |||||
} | |||||
return REDIS_OK; | |||||
} |
@@ -0,0 +1,122 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __HIREDIS_READ_H | |||||
#define __HIREDIS_READ_H | |||||
#include <stdio.h> /* for size_t */ | |||||
#define REDIS_ERR -1 | |||||
#define REDIS_OK 0 | |||||
/* When an error occurs, the err flag in a context is set to hold the type of | |||||
* error that occurred. REDIS_ERR_IO means there was an I/O error and you | |||||
* should use the "errno" variable to find out what is wrong. | |||||
* For other values, the "errstr" field will hold a description. */ | |||||
#define REDIS_ERR_IO 1 /* Error in read or write */ | |||||
#define REDIS_ERR_EOF 3 /* End of file */ | |||||
#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ | |||||
#define REDIS_ERR_OOM 5 /* Out of memory */ | |||||
#define REDIS_ERR_TIMEOUT 6 /* Timed out */ | |||||
#define REDIS_ERR_OTHER 2 /* Everything else... */ | |||||
#define REDIS_REPLY_STRING 1 | |||||
#define REDIS_REPLY_ARRAY 2 | |||||
#define REDIS_REPLY_INTEGER 3 | |||||
#define REDIS_REPLY_NIL 4 | |||||
#define REDIS_REPLY_STATUS 5 | |||||
#define REDIS_REPLY_ERROR 6 | |||||
#define REDIS_REPLY_DOUBLE 7 | |||||
#define REDIS_REPLY_BOOL 8 | |||||
#define REDIS_REPLY_VERB 9 | |||||
#define REDIS_REPLY_MAP 9 | |||||
#define REDIS_REPLY_SET 10 | |||||
#define REDIS_REPLY_ATTR 11 | |||||
#define REDIS_REPLY_PUSH 12 | |||||
#define REDIS_REPLY_BIGNUM 13 | |||||
#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
typedef struct redisReadTask { | |||||
int type; | |||||
int elements; /* number of elements in multibulk container */ | |||||
int idx; /* index in parent (array) object */ | |||||
void *obj; /* holds user-generated value for a read task */ | |||||
struct redisReadTask *parent; /* parent task */ | |||||
void *privdata; /* user-settable arbitrary field */ | |||||
} redisReadTask; | |||||
typedef struct redisReplyObjectFunctions { | |||||
void *(*createString)(const redisReadTask*, char*, size_t); | |||||
void *(*createArray)(const redisReadTask*, size_t); | |||||
void *(*createInteger)(const redisReadTask*, long long); | |||||
void *(*createDouble)(const redisReadTask*, double, char*, size_t); | |||||
void *(*createNil)(const redisReadTask*); | |||||
void *(*createBool)(const redisReadTask*, int); | |||||
void (*freeObject)(void*); | |||||
} redisReplyObjectFunctions; | |||||
typedef struct redisReader { | |||||
int err; /* Error flags, 0 when there is no error */ | |||||
char errstr[128]; /* String representation of error when applicable */ | |||||
char *buf; /* Read buffer */ | |||||
size_t pos; /* Buffer cursor */ | |||||
size_t len; /* Buffer length */ | |||||
size_t maxbuf; /* Max length of unused buffer */ | |||||
redisReadTask rstack[9]; | |||||
int ridx; /* Index of current read task */ | |||||
void *reply; /* Temporary reply pointer */ | |||||
redisReplyObjectFunctions *fn; | |||||
void *privdata; | |||||
} redisReader; | |||||
/* Public API for the protocol parser. */ | |||||
redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); | |||||
void redisReaderFree(redisReader *r); | |||||
int redisReaderFeed(redisReader *r, const char *buf, size_t len); | |||||
int redisReaderGetReply(redisReader *r, void **reply); | |||||
#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) | |||||
#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) | |||||
#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
#endif |
@@ -0,0 +1,276 @@ | |||||
/* SDSLib 2.0 -- A C dynamic strings library | |||||
* | |||||
* Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2015, Oran Agra | |||||
* Copyright (c) 2015, Redis Labs, Inc | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __SDS_H | |||||
#define __SDS_H | |||||
#define SDS_MAX_PREALLOC (1024*1024) | |||||
#ifdef _MSC_VER | |||||
#define __attribute__(x) | |||||
#endif | |||||
#include <sys/types.h> | |||||
#include <stdarg.h> | |||||
#include <stdint.h> | |||||
typedef char *sds; | |||||
/* Note: sdshdr5 is never used, we just access the flags byte directly. | |||||
* However is here to document the layout of type 5 SDS strings. */ | |||||
struct __attribute__ ((__packed__)) sdshdr5 { | |||||
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ | |||||
char buf[]; | |||||
}; | |||||
struct __attribute__ ((__packed__)) sdshdr8 { | |||||
uint8_t len; /* used */ | |||||
uint8_t alloc; /* excluding the header and null terminator */ | |||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */ | |||||
char buf[]; | |||||
}; | |||||
struct __attribute__ ((__packed__)) sdshdr16 { | |||||
uint16_t len; /* used */ | |||||
uint16_t alloc; /* excluding the header and null terminator */ | |||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */ | |||||
char buf[]; | |||||
}; | |||||
struct __attribute__ ((__packed__)) sdshdr32 { | |||||
uint32_t len; /* used */ | |||||
uint32_t alloc; /* excluding the header and null terminator */ | |||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */ | |||||
char buf[]; | |||||
}; | |||||
struct __attribute__ ((__packed__)) sdshdr64 { | |||||
uint64_t len; /* used */ | |||||
uint64_t alloc; /* excluding the header and null terminator */ | |||||
unsigned char flags; /* 3 lsb of type, 5 unused bits */ | |||||
char buf[]; | |||||
}; | |||||
#define SDS_TYPE_5 0 | |||||
#define SDS_TYPE_8 1 | |||||
#define SDS_TYPE_16 2 | |||||
#define SDS_TYPE_32 3 | |||||
#define SDS_TYPE_64 4 | |||||
#define SDS_TYPE_MASK 7 | |||||
#define SDS_TYPE_BITS 3 | |||||
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); | |||||
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) | |||||
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) | |||||
static inline size_t sdslen(const sds s) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: | |||||
return SDS_TYPE_5_LEN(flags); | |||||
case SDS_TYPE_8: | |||||
return SDS_HDR(8,s)->len; | |||||
case SDS_TYPE_16: | |||||
return SDS_HDR(16,s)->len; | |||||
case SDS_TYPE_32: | |||||
return SDS_HDR(32,s)->len; | |||||
case SDS_TYPE_64: | |||||
return SDS_HDR(64,s)->len; | |||||
} | |||||
return 0; | |||||
} | |||||
static inline size_t sdsavail(const sds s) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: { | |||||
return 0; | |||||
} | |||||
case SDS_TYPE_8: { | |||||
SDS_HDR_VAR(8,s); | |||||
return sh->alloc - sh->len; | |||||
} | |||||
case SDS_TYPE_16: { | |||||
SDS_HDR_VAR(16,s); | |||||
return sh->alloc - sh->len; | |||||
} | |||||
case SDS_TYPE_32: { | |||||
SDS_HDR_VAR(32,s); | |||||
return sh->alloc - sh->len; | |||||
} | |||||
case SDS_TYPE_64: { | |||||
SDS_HDR_VAR(64,s); | |||||
return sh->alloc - sh->len; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
static inline void sdssetlen(sds s, size_t newlen) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: | |||||
{ | |||||
unsigned char *fp = ((unsigned char*)s)-1; | |||||
*fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS)); | |||||
} | |||||
break; | |||||
case SDS_TYPE_8: | |||||
SDS_HDR(8,s)->len = (uint8_t)newlen; | |||||
break; | |||||
case SDS_TYPE_16: | |||||
SDS_HDR(16,s)->len = (uint16_t)newlen; | |||||
break; | |||||
case SDS_TYPE_32: | |||||
SDS_HDR(32,s)->len = (uint32_t)newlen; | |||||
break; | |||||
case SDS_TYPE_64: | |||||
SDS_HDR(64,s)->len = (uint64_t)newlen; | |||||
break; | |||||
} | |||||
} | |||||
static inline void sdsinclen(sds s, size_t inc) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: | |||||
{ | |||||
unsigned char *fp = ((unsigned char*)s)-1; | |||||
unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc; | |||||
*fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); | |||||
} | |||||
break; | |||||
case SDS_TYPE_8: | |||||
SDS_HDR(8,s)->len += (uint8_t)inc; | |||||
break; | |||||
case SDS_TYPE_16: | |||||
SDS_HDR(16,s)->len += (uint16_t)inc; | |||||
break; | |||||
case SDS_TYPE_32: | |||||
SDS_HDR(32,s)->len += (uint32_t)inc; | |||||
break; | |||||
case SDS_TYPE_64: | |||||
SDS_HDR(64,s)->len += (uint64_t)inc; | |||||
break; | |||||
} | |||||
} | |||||
/* sdsalloc() = sdsavail() + sdslen() */ | |||||
static inline size_t sdsalloc(const sds s) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: | |||||
return SDS_TYPE_5_LEN(flags); | |||||
case SDS_TYPE_8: | |||||
return SDS_HDR(8,s)->alloc; | |||||
case SDS_TYPE_16: | |||||
return SDS_HDR(16,s)->alloc; | |||||
case SDS_TYPE_32: | |||||
return SDS_HDR(32,s)->alloc; | |||||
case SDS_TYPE_64: | |||||
return SDS_HDR(64,s)->alloc; | |||||
} | |||||
return 0; | |||||
} | |||||
static inline void sdssetalloc(sds s, size_t newlen) { | |||||
unsigned char flags = s[-1]; | |||||
switch(flags&SDS_TYPE_MASK) { | |||||
case SDS_TYPE_5: | |||||
/* Nothing to do, this type has no total allocation info. */ | |||||
break; | |||||
case SDS_TYPE_8: | |||||
SDS_HDR(8,s)->alloc = (uint8_t)newlen; | |||||
break; | |||||
case SDS_TYPE_16: | |||||
SDS_HDR(16,s)->alloc = (uint16_t)newlen; | |||||
break; | |||||
case SDS_TYPE_32: | |||||
SDS_HDR(32,s)->alloc = (uint32_t)newlen; | |||||
break; | |||||
case SDS_TYPE_64: | |||||
SDS_HDR(64,s)->alloc = (uint64_t)newlen; | |||||
break; | |||||
} | |||||
} | |||||
sds sdsnewlen(const void *init, size_t initlen); | |||||
sds sdsnew(const char *init); | |||||
sds sdsempty(void); | |||||
sds sdsdup(const sds s); | |||||
void sdsfree(sds s); | |||||
sds sdsgrowzero(sds s, size_t len); | |||||
sds sdscatlen(sds s, const void *t, size_t len); | |||||
sds sdscat(sds s, const char *t); | |||||
sds sdscatsds(sds s, const sds t); | |||||
sds sdscpylen(sds s, const char *t, size_t len); | |||||
sds sdscpy(sds s, const char *t); | |||||
sds sdscatvprintf(sds s, const char *fmt, va_list ap); | |||||
#ifdef __GNUC__ | |||||
sds sdscatprintf(sds s, const char *fmt, ...) | |||||
__attribute__((format(printf, 2, 3))); | |||||
#else | |||||
sds sdscatprintf(sds s, const char *fmt, ...); | |||||
#endif | |||||
sds sdscatfmt(sds s, char const *fmt, ...); | |||||
sds sdstrim(sds s, const char *cset); | |||||
void sdsrange(sds s, int start, int end); | |||||
void sdsupdatelen(sds s); | |||||
void sdsclear(sds s); | |||||
int sdscmp(const sds s1, const sds s2); | |||||
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); | |||||
void sdsfreesplitres(sds *tokens, int count); | |||||
void sdstolower(sds s); | |||||
void sdstoupper(sds s); | |||||
sds sdsfromlonglong(long long value); | |||||
sds sdscatrepr(sds s, const char *p, size_t len); | |||||
sds *sdssplitargs(const char *line, int *argc); | |||||
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); | |||||
sds sdsjoin(char **argv, int argc, char *sep); | |||||
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); | |||||
/* Low level functions exposed to the user API */ | |||||
sds sdsMakeRoomFor(sds s, size_t addlen); | |||||
void sdsIncrLen(sds s, int incr); | |||||
sds sdsRemoveFreeSpace(sds s); | |||||
size_t sdsAllocSize(sds s); | |||||
void *sdsAllocPtr(sds s); | |||||
/* Export the allocator used by SDS to the program using SDS. | |||||
* Sometimes the program SDS is linked to, may use a different set of | |||||
* allocators, but may want to allocate or free things that SDS will | |||||
* respectively free or allocate. */ | |||||
void *sds_malloc(size_t size); | |||||
void *sds_realloc(void *ptr, size_t size); | |||||
void sds_free(void *ptr); | |||||
#ifdef REDIS_TEST | |||||
int sdsTest(int argc, char *argv[]); | |||||
#endif | |||||
#endif |
@@ -0,0 +1,42 @@ | |||||
/* SDSLib 2.0 -- A C dynamic strings library | |||||
* | |||||
* Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2015, Oran Agra | |||||
* Copyright (c) 2015, Redis Labs, Inc | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
/* SDS allocator selection. | |||||
* | |||||
* This file is used in order to change the SDS allocator at compile time. | |||||
* Just define the following defines to what you want to use. Also add | |||||
* the include of your alternate allocator if needed (not needed in order | |||||
* to use the default libc allocator). */ | |||||
#define s_malloc malloc | |||||
#define s_realloc realloc | |||||
#define s_free free |
@@ -0,0 +1,248 @@ | |||||
/* | |||||
* Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#define REDIS_SOCKCOMPAT_IMPLEMENTATION | |||||
#include "sockcompat.h" | |||||
#ifdef _WIN32 | |||||
static int _wsaErrorToErrno(int err) { | |||||
switch (err) { | |||||
case WSAEWOULDBLOCK: | |||||
return EWOULDBLOCK; | |||||
case WSAEINPROGRESS: | |||||
return EINPROGRESS; | |||||
case WSAEALREADY: | |||||
return EALREADY; | |||||
case WSAENOTSOCK: | |||||
return ENOTSOCK; | |||||
case WSAEDESTADDRREQ: | |||||
return EDESTADDRREQ; | |||||
case WSAEMSGSIZE: | |||||
return EMSGSIZE; | |||||
case WSAEPROTOTYPE: | |||||
return EPROTOTYPE; | |||||
case WSAENOPROTOOPT: | |||||
return ENOPROTOOPT; | |||||
case WSAEPROTONOSUPPORT: | |||||
return EPROTONOSUPPORT; | |||||
case WSAEOPNOTSUPP: | |||||
return EOPNOTSUPP; | |||||
case WSAEAFNOSUPPORT: | |||||
return EAFNOSUPPORT; | |||||
case WSAEADDRINUSE: | |||||
return EADDRINUSE; | |||||
case WSAEADDRNOTAVAIL: | |||||
return EADDRNOTAVAIL; | |||||
case WSAENETDOWN: | |||||
return ENETDOWN; | |||||
case WSAENETUNREACH: | |||||
return ENETUNREACH; | |||||
case WSAENETRESET: | |||||
return ENETRESET; | |||||
case WSAECONNABORTED: | |||||
return ECONNABORTED; | |||||
case WSAECONNRESET: | |||||
return ECONNRESET; | |||||
case WSAENOBUFS: | |||||
return ENOBUFS; | |||||
case WSAEISCONN: | |||||
return EISCONN; | |||||
case WSAENOTCONN: | |||||
return ENOTCONN; | |||||
case WSAETIMEDOUT: | |||||
return ETIMEDOUT; | |||||
case WSAECONNREFUSED: | |||||
return ECONNREFUSED; | |||||
case WSAELOOP: | |||||
return ELOOP; | |||||
case WSAENAMETOOLONG: | |||||
return ENAMETOOLONG; | |||||
case WSAEHOSTUNREACH: | |||||
return EHOSTUNREACH; | |||||
case WSAENOTEMPTY: | |||||
return ENOTEMPTY; | |||||
default: | |||||
/* We just return a generic I/O error if we could not find a relevant error. */ | |||||
return EIO; | |||||
} | |||||
} | |||||
static void _updateErrno(int success) { | |||||
errno = success ? 0 : _wsaErrorToErrno(WSAGetLastError()); | |||||
} | |||||
static int _initWinsock() { | |||||
static int s_initialized = 0; | |||||
if (!s_initialized) { | |||||
static WSADATA wsadata; | |||||
int err = WSAStartup(MAKEWORD(2,2), &wsadata); | |||||
if (err != 0) { | |||||
errno = _wsaErrorToErrno(err); | |||||
return 0; | |||||
} | |||||
s_initialized = 1; | |||||
} | |||||
return 1; | |||||
} | |||||
int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { | |||||
/* Note: This function is likely to be called before other functions, so run init here. */ | |||||
if (!_initWinsock()) { | |||||
return EAI_FAIL; | |||||
} | |||||
switch (getaddrinfo(node, service, hints, res)) { | |||||
case 0: return 0; | |||||
case WSATRY_AGAIN: return EAI_AGAIN; | |||||
case WSAEINVAL: return EAI_BADFLAGS; | |||||
case WSAEAFNOSUPPORT: return EAI_FAMILY; | |||||
case WSA_NOT_ENOUGH_MEMORY: return EAI_MEMORY; | |||||
case WSAHOST_NOT_FOUND: return EAI_NONAME; | |||||
case WSATYPE_NOT_FOUND: return EAI_SERVICE; | |||||
case WSAESOCKTNOSUPPORT: return EAI_SOCKTYPE; | |||||
default: return EAI_FAIL; /* Including WSANO_RECOVERY */ | |||||
} | |||||
} | |||||
const char *win32_gai_strerror(int errcode) { | |||||
switch (errcode) { | |||||
case 0: errcode = 0; break; | |||||
case EAI_AGAIN: errcode = WSATRY_AGAIN; break; | |||||
case EAI_BADFLAGS: errcode = WSAEINVAL; break; | |||||
case EAI_FAMILY: errcode = WSAEAFNOSUPPORT; break; | |||||
case EAI_MEMORY: errcode = WSA_NOT_ENOUGH_MEMORY; break; | |||||
case EAI_NONAME: errcode = WSAHOST_NOT_FOUND; break; | |||||
case EAI_SERVICE: errcode = WSATYPE_NOT_FOUND; break; | |||||
case EAI_SOCKTYPE: errcode = WSAESOCKTNOSUPPORT; break; | |||||
default: errcode = WSANO_RECOVERY; break; /* Including EAI_FAIL */ | |||||
} | |||||
return gai_strerror(errcode); | |||||
} | |||||
void win32_freeaddrinfo(struct addrinfo *res) { | |||||
freeaddrinfo(res); | |||||
} | |||||
SOCKET win32_socket(int domain, int type, int protocol) { | |||||
SOCKET s; | |||||
/* Note: This function is likely to be called before other functions, so run init here. */ | |||||
if (!_initWinsock()) { | |||||
return INVALID_SOCKET; | |||||
} | |||||
_updateErrno((s = socket(domain, type, protocol)) != INVALID_SOCKET); | |||||
return s; | |||||
} | |||||
int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp) { | |||||
int ret = ioctlsocket(fd, (long)request, argp); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { | |||||
int ret = bind(sockfd, addr, addrlen); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { | |||||
int ret = connect(sockfd, addr, addrlen); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
/* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as | |||||
* EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX | |||||
* logic consistent. */ | |||||
if (errno == EWOULDBLOCK) { | |||||
errno = EINPROGRESS; | |||||
} | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) { | |||||
int ret = 0; | |||||
if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { | |||||
if (*optlen >= sizeof (struct timeval)) { | |||||
struct timeval *tv = optval; | |||||
DWORD timeout = 0; | |||||
socklen_t dwlen = 0; | |||||
ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen); | |||||
tv->tv_sec = timeout / 1000; | |||||
tv->tv_usec = (timeout * 1000) % 1000000; | |||||
} else { | |||||
ret = WSAEFAULT; | |||||
} | |||||
*optlen = sizeof (struct timeval); | |||||
} else { | |||||
ret = getsockopt(sockfd, level, optname, (char*)optval, optlen); | |||||
} | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) { | |||||
int ret = 0; | |||||
if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { | |||||
struct timeval *tv = optval; | |||||
DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; | |||||
ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD)); | |||||
} else { | |||||
ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen); | |||||
} | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_close(SOCKET fd) { | |||||
int ret = closesocket(fd); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags) { | |||||
int ret = recv(sockfd, (char*)buf, (int)len, flags); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags) { | |||||
int ret = send(sockfd, (const char*)buf, (int)len, flags); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) { | |||||
int ret = WSAPoll(fds, nfds, timeout); | |||||
_updateErrno(ret != SOCKET_ERROR); | |||||
return ret != SOCKET_ERROR ? ret : -1; | |||||
} | |||||
#endif /* _WIN32 */ |
@@ -0,0 +1,91 @@ | |||||
/* | |||||
* Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu> | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __SOCKCOMPAT_H | |||||
#define __SOCKCOMPAT_H | |||||
#ifndef _WIN32 | |||||
/* For POSIX systems we use the standard BSD socket API. */ | |||||
#include <unistd.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/select.h> | |||||
#include <sys/un.h> | |||||
#include <netinet/in.h> | |||||
#include <netinet/tcp.h> | |||||
#include <arpa/inet.h> | |||||
#include <netdb.h> | |||||
#include <poll.h> | |||||
#else | |||||
/* For Windows we use winsock. */ | |||||
#undef _WIN32_WINNT | |||||
#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */ | |||||
#include <winsock2.h> | |||||
#include <ws2tcpip.h> | |||||
#include <stddef.h> | |||||
#ifdef _MSC_VER | |||||
typedef signed long ssize_t; | |||||
#endif | |||||
/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */ | |||||
int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); | |||||
const char *win32_gai_strerror(int errcode); | |||||
void win32_freeaddrinfo(struct addrinfo *res); | |||||
SOCKET win32_socket(int domain, int type, int protocol); | |||||
int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp); | |||||
int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); | |||||
int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); | |||||
int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen); | |||||
int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen); | |||||
int win32_close(SOCKET fd); | |||||
ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags); | |||||
ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); | |||||
typedef ULONG nfds_t; | |||||
int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); | |||||
#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION | |||||
#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) | |||||
#undef gai_strerror | |||||
#define gai_strerror(errcode) win32_gai_strerror(errcode) | |||||
#define freeaddrinfo(res) win32_freeaddrinfo(res) | |||||
#define socket(domain, type, protocol) win32_socket(domain, type, protocol) | |||||
#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp) | |||||
#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen) | |||||
#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen) | |||||
#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen) | |||||
#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen) | |||||
#define close(fd) win32_close(fd) | |||||
#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) | |||||
#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) | |||||
#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) | |||||
#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ | |||||
#endif /* _WIN32 */ | |||||
#endif /* __SOCKCOMPAT_H */ |
@@ -0,0 +1,448 @@ | |||||
/* | |||||
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> | |||||
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> | |||||
* Copyright (c) 2019, Redis Labs | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions are met: | |||||
* | |||||
* * Redistributions of source code must retain the above copyright notice, | |||||
* this list of conditions and the following disclaimer. | |||||
* * Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* * Neither the name of Redis nor the names of its contributors may be used | |||||
* to endorse or promote products derived from this software without | |||||
* specific prior written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
* POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include "hiredis.h" | |||||
#include "async.h" | |||||
#include <assert.h> | |||||
#include <pthread.h> | |||||
#include <errno.h> | |||||
#include <string.h> | |||||
#include <openssl/ssl.h> | |||||
#include <openssl/err.h> | |||||
#include "async_private.h" | |||||
void __redisSetError(redisContext *c, int type, const char *str); | |||||
/* The SSL context is attached to SSL/TLS connections as a privdata. */ | |||||
typedef struct redisSSLContext { | |||||
/** | |||||
* OpenSSL SSL_CTX; It is optional and will not be set when using | |||||
* user-supplied SSL. | |||||
*/ | |||||
SSL_CTX *ssl_ctx; | |||||
/** | |||||
* OpenSSL SSL object. | |||||
*/ | |||||
SSL *ssl; | |||||
/** | |||||
* SSL_write() requires to be called again with the same arguments it was | |||||
* previously called with in the event of an SSL_read/SSL_write situation | |||||
*/ | |||||
size_t lastLen; | |||||
/** Whether the SSL layer requires read (possibly before a write) */ | |||||
int wantRead; | |||||
/** | |||||
* Whether a write was requested prior to a read. If set, the write() | |||||
* should resume whenever a read takes place, if possible | |||||
*/ | |||||
int pendingWrite; | |||||
} redisSSLContext; | |||||
/* Forward declaration */ | |||||
redisContextFuncs redisContextSSLFuncs; | |||||
#ifdef HIREDIS_SSL_TRACE | |||||
/** | |||||
* Callback used for debugging | |||||
*/ | |||||
static void sslLogCallback(const SSL *ssl, int where, int ret) { | |||||
const char *retstr; | |||||
int should_log = 0; | |||||
/* Ignore low-level SSL stuff */ | |||||
if (where & SSL_CB_ALERT) { | |||||
should_log = 1; | |||||
} | |||||
if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) { | |||||
should_log = 1; | |||||
} | |||||
if ((where & SSL_CB_EXIT) && ret == 0) { | |||||
should_log = 1; | |||||
} | |||||
if (!should_log) { | |||||
return; | |||||
} | |||||
retstr = SSL_alert_type_string(ret); | |||||
printf("ST(0x%x). %s. R(0x%x)%s\n", where, SSL_state_string_long(ssl), ret, retstr); | |||||
if (where == SSL_CB_HANDSHAKE_DONE) { | |||||
printf("Using SSL version %s. Cipher=%s\n", SSL_get_version(ssl), SSL_get_cipher_name(ssl)); | |||||
} | |||||
} | |||||
#endif | |||||
/** | |||||
* OpenSSL global initialization and locking handling callbacks. | |||||
* Note that this is only required for OpenSSL < 1.1.0. | |||||
*/ | |||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||||
#define HIREDIS_USE_CRYPTO_LOCKS | |||||
#endif | |||||
#ifdef HIREDIS_USE_CRYPTO_LOCKS | |||||
typedef pthread_mutex_t sslLockType; | |||||
static void sslLockInit(sslLockType *l) { | |||||
pthread_mutex_init(l, NULL); | |||||
} | |||||
static void sslLockAcquire(sslLockType *l) { | |||||
pthread_mutex_lock(l); | |||||
} | |||||
static void sslLockRelease(sslLockType *l) { | |||||
pthread_mutex_unlock(l); | |||||
} | |||||
static pthread_mutex_t *ossl_locks; | |||||
static void opensslDoLock(int mode, int lkid, const char *f, int line) { | |||||
sslLockType *l = ossl_locks + lkid; | |||||
if (mode & CRYPTO_LOCK) { | |||||
sslLockAcquire(l); | |||||
} else { | |||||
sslLockRelease(l); | |||||
} | |||||
(void)f; | |||||
(void)line; | |||||
} | |||||
static void initOpensslLocks(void) { | |||||
unsigned ii, nlocks; | |||||
if (CRYPTO_get_locking_callback() != NULL) { | |||||
/* Someone already set the callback before us. Don't destroy it! */ | |||||
return; | |||||
} | |||||
nlocks = CRYPTO_num_locks(); | |||||
ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks); | |||||
for (ii = 0; ii < nlocks; ii++) { | |||||
sslLockInit(ossl_locks + ii); | |||||
} | |||||
CRYPTO_set_locking_callback(opensslDoLock); | |||||
} | |||||
#endif /* HIREDIS_USE_CRYPTO_LOCKS */ | |||||
/** | |||||
* SSL Connection initialization. | |||||
*/ | |||||
static int redisSSLConnect(redisContext *c, SSL_CTX *ssl_ctx, SSL *ssl) { | |||||
if (c->privdata) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated"); | |||||
return REDIS_ERR; | |||||
} | |||||
c->privdata = calloc(1, sizeof(redisSSLContext)); | |||||
c->funcs = &redisContextSSLFuncs; | |||||
redisSSLContext *rssl = c->privdata; | |||||
rssl->ssl_ctx = ssl_ctx; | |||||
rssl->ssl = ssl; | |||||
SSL_set_mode(rssl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); | |||||
SSL_set_fd(rssl->ssl, c->fd); | |||||
SSL_set_connect_state(rssl->ssl); | |||||
ERR_clear_error(); | |||||
int rv = SSL_connect(rssl->ssl); | |||||
if (rv == 1) { | |||||
return REDIS_OK; | |||||
} | |||||
rv = SSL_get_error(rssl->ssl, rv); | |||||
if (((c->flags & REDIS_BLOCK) == 0) && | |||||
(rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) { | |||||
return REDIS_OK; | |||||
} | |||||
if (c->err == 0) { | |||||
char err[512]; | |||||
if (rv == SSL_ERROR_SYSCALL) | |||||
snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno)); | |||||
else { | |||||
unsigned long e = ERR_peek_last_error(); | |||||
snprintf(err,sizeof(err)-1,"SSL_connect failed: %s", | |||||
ERR_reason_error_string(e)); | |||||
} | |||||
__redisSetError(c, REDIS_ERR_IO, err); | |||||
} | |||||
return REDIS_ERR; | |||||
} | |||||
int redisInitiateSSL(redisContext *c, SSL *ssl) { | |||||
return redisSSLConnect(c, NULL, ssl); | |||||
} | |||||
int redisSecureConnection(redisContext *c, const char *capath, | |||||
const char *certpath, const char *keypath, const char *servername) { | |||||
SSL_CTX *ssl_ctx = NULL; | |||||
SSL *ssl = NULL; | |||||
/* Initialize global OpenSSL stuff */ | |||||
static int isInit = 0; | |||||
if (!isInit) { | |||||
isInit = 1; | |||||
SSL_library_init(); | |||||
#ifdef HIREDIS_USE_CRYPTO_LOCKS | |||||
initOpensslLocks(); | |||||
#endif | |||||
} | |||||
ssl_ctx = SSL_CTX_new(SSLv23_client_method()); | |||||
if (!ssl_ctx) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Failed to create SSL_CTX"); | |||||
goto error; | |||||
} | |||||
#ifdef HIREDIS_SSL_TRACE | |||||
SSL_CTX_set_info_callback(ssl_ctx, sslLogCallback); | |||||
#endif | |||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); | |||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); | |||||
if ((certpath != NULL && keypath == NULL) || (keypath != NULL && certpath == NULL)) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "certpath and keypath must be specified together"); | |||||
goto error; | |||||
} | |||||
if (capath) { | |||||
if (!SSL_CTX_load_verify_locations(ssl_ctx, capath, NULL)) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Invalid CA certificate"); | |||||
goto error; | |||||
} | |||||
} | |||||
if (certpath) { | |||||
if (!SSL_CTX_use_certificate_chain_file(ssl_ctx, certpath)) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Invalid client certificate"); | |||||
goto error; | |||||
} | |||||
if (!SSL_CTX_use_PrivateKey_file(ssl_ctx, keypath, SSL_FILETYPE_PEM)) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Invalid client key"); | |||||
goto error; | |||||
} | |||||
} | |||||
ssl = SSL_new(ssl_ctx); | |||||
if (!ssl) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance"); | |||||
goto error; | |||||
} | |||||
if (servername) { | |||||
if (!SSL_set_tlsext_host_name(ssl, servername)) { | |||||
__redisSetError(c, REDIS_ERR_OTHER, "Couldn't set server name indication"); | |||||
goto error; | |||||
} | |||||
} | |||||
return redisSSLConnect(c, ssl_ctx, ssl); | |||||
error: | |||||
if (ssl) SSL_free(ssl); | |||||
if (ssl_ctx) SSL_CTX_free(ssl_ctx); | |||||
return REDIS_ERR; | |||||
} | |||||
static int maybeCheckWant(redisSSLContext *rssl, int rv) { | |||||
/** | |||||
* If the error is WANT_READ or WANT_WRITE, the appropriate flags are set | |||||
* and true is returned. False is returned otherwise | |||||
*/ | |||||
if (rv == SSL_ERROR_WANT_READ) { | |||||
rssl->wantRead = 1; | |||||
return 1; | |||||
} else if (rv == SSL_ERROR_WANT_WRITE) { | |||||
rssl->pendingWrite = 1; | |||||
return 1; | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
/** | |||||
* Implementation of redisContextFuncs for SSL connections. | |||||
*/ | |||||
static void redisSSLFreeContext(void *privdata){ | |||||
redisSSLContext *rsc = privdata; | |||||
if (!rsc) return; | |||||
if (rsc->ssl) { | |||||
SSL_free(rsc->ssl); | |||||
rsc->ssl = NULL; | |||||
} | |||||
if (rsc->ssl_ctx) { | |||||
SSL_CTX_free(rsc->ssl_ctx); | |||||
rsc->ssl_ctx = NULL; | |||||
} | |||||
free(rsc); | |||||
} | |||||
static int redisSSLRead(redisContext *c, char *buf, size_t bufcap) { | |||||
redisSSLContext *rssl = c->privdata; | |||||
int nread = SSL_read(rssl->ssl, buf, bufcap); | |||||
if (nread > 0) { | |||||
return nread; | |||||
} else if (nread == 0) { | |||||
__redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); | |||||
return -1; | |||||
} else { | |||||
int err = SSL_get_error(rssl->ssl, nread); | |||||
if (c->flags & REDIS_BLOCK) { | |||||
/** | |||||
* In blocking mode, we should never end up in a situation where | |||||
* we get an error without it being an actual error, except | |||||
* in the case of EINTR, which can be spuriously received from | |||||
* debuggers or whatever. | |||||
*/ | |||||
if (errno == EINTR) { | |||||
return 0; | |||||
} else { | |||||
const char *msg = NULL; | |||||
if (errno == EAGAIN) { | |||||
msg = "Resource temporarily unavailable"; | |||||
} | |||||
__redisSetError(c, REDIS_ERR_IO, msg); | |||||
return -1; | |||||
} | |||||
} | |||||
/** | |||||
* We can very well get an EWOULDBLOCK/EAGAIN, however | |||||
*/ | |||||
if (maybeCheckWant(rssl, err)) { | |||||
return 0; | |||||
} else { | |||||
__redisSetError(c, REDIS_ERR_IO, NULL); | |||||
return -1; | |||||
} | |||||
} | |||||
} | |||||
static int redisSSLWrite(redisContext *c) { | |||||
redisSSLContext *rssl = c->privdata; | |||||
size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf); | |||||
int rv = SSL_write(rssl->ssl, c->obuf, len); | |||||
if (rv > 0) { | |||||
rssl->lastLen = 0; | |||||
} else if (rv < 0) { | |||||
rssl->lastLen = len; | |||||
int err = SSL_get_error(rssl->ssl, rv); | |||||
if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) { | |||||
return 0; | |||||
} else { | |||||
__redisSetError(c, REDIS_ERR_IO, NULL); | |||||
return -1; | |||||
} | |||||
} | |||||
return rv; | |||||
} | |||||
static void redisSSLAsyncRead(redisAsyncContext *ac) { | |||||
int rv; | |||||
redisSSLContext *rssl = ac->c.privdata; | |||||
redisContext *c = &ac->c; | |||||
rssl->wantRead = 0; | |||||
if (rssl->pendingWrite) { | |||||
int done; | |||||
/* This is probably just a write event */ | |||||
rssl->pendingWrite = 0; | |||||
rv = redisBufferWrite(c, &done); | |||||
if (rv == REDIS_ERR) { | |||||
__redisAsyncDisconnect(ac); | |||||
return; | |||||
} else if (!done) { | |||||
_EL_ADD_WRITE(ac); | |||||
} | |||||
} | |||||
rv = redisBufferRead(c); | |||||
if (rv == REDIS_ERR) { | |||||
__redisAsyncDisconnect(ac); | |||||
} else { | |||||
_EL_ADD_READ(ac); | |||||
redisProcessCallbacks(ac); | |||||
} | |||||
} | |||||
static void redisSSLAsyncWrite(redisAsyncContext *ac) { | |||||
int rv, done = 0; | |||||
redisSSLContext *rssl = ac->c.privdata; | |||||
redisContext *c = &ac->c; | |||||
rssl->pendingWrite = 0; | |||||
rv = redisBufferWrite(c, &done); | |||||
if (rv == REDIS_ERR) { | |||||
__redisAsyncDisconnect(ac); | |||||
return; | |||||
} | |||||
if (!done) { | |||||
if (rssl->wantRead) { | |||||
/* Need to read-before-write */ | |||||
rssl->pendingWrite = 1; | |||||
_EL_DEL_WRITE(ac); | |||||
} else { | |||||
/* No extra reads needed, just need to write more */ | |||||
_EL_ADD_WRITE(ac); | |||||
} | |||||
} else { | |||||
/* Already done! */ | |||||
_EL_DEL_WRITE(ac); | |||||
} | |||||
/* Always reschedule a read */ | |||||
_EL_ADD_READ(ac); | |||||
} | |||||
redisContextFuncs redisContextSSLFuncs = { | |||||
.free_privdata = redisSSLFreeContext, | |||||
.async_read = redisSSLAsyncRead, | |||||
.async_write = redisSSLAsyncWrite, | |||||
.read = redisSSLRead, | |||||
.write = redisSSLWrite | |||||
}; | |||||
@@ -0,0 +1,70 @@ | |||||
#!/bin/sh -ue | |||||
REDIS_SERVER=${REDIS_SERVER:-redis-server} | |||||
REDIS_PORT=${REDIS_PORT:-56379} | |||||
REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443} | |||||
TEST_SSL=${TEST_SSL:-0} | |||||
SSL_TEST_ARGS= | |||||
tmpdir=$(mktemp -d) | |||||
PID_FILE=${tmpdir}/hiredis-test-redis.pid | |||||
SOCK_FILE=${tmpdir}/hiredis-test-redis.sock | |||||
if [ "$TEST_SSL" = "1" ]; then | |||||
SSL_CA_CERT=${tmpdir}/ca.crt | |||||
SSL_CA_KEY=${tmpdir}/ca.key | |||||
SSL_CERT=${tmpdir}/redis.crt | |||||
SSL_KEY=${tmpdir}/redis.key | |||||
openssl genrsa -out ${tmpdir}/ca.key 4096 | |||||
openssl req \ | |||||
-x509 -new -nodes -sha256 \ | |||||
-key ${SSL_CA_KEY} \ | |||||
-days 3650 \ | |||||
-subj '/CN=Hiredis Test CA' \ | |||||
-out ${SSL_CA_CERT} | |||||
openssl genrsa -out ${SSL_KEY} 2048 | |||||
openssl req \ | |||||
-new -sha256 \ | |||||
-key ${SSL_KEY} \ | |||||
-subj '/CN=Hiredis Test Cert' | \ | |||||
openssl x509 \ | |||||
-req -sha256 \ | |||||
-CA ${SSL_CA_CERT} \ | |||||
-CAkey ${SSL_CA_KEY} \ | |||||
-CAserial ${tmpdir}/ca.txt \ | |||||
-CAcreateserial \ | |||||
-days 365 \ | |||||
-out ${SSL_CERT} | |||||
SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${REDIS_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}" | |||||
fi | |||||
cleanup() { | |||||
set +e | |||||
kill $(cat ${PID_FILE}) | |||||
rm -rf ${tmpdir} | |||||
} | |||||
trap cleanup INT TERM EXIT | |||||
cat > ${tmpdir}/redis.conf <<EOF | |||||
daemonize yes | |||||
pidfile ${PID_FILE} | |||||
port ${REDIS_PORT} | |||||
bind 127.0.0.1 | |||||
unixsocket ${SOCK_FILE} | |||||
EOF | |||||
if [ "$TEST_SSL" = "1" ]; then | |||||
cat >> ${tmpdir}/redis.conf <<EOF | |||||
tls-port ${REDIS_SSL_PORT} | |||||
tls-ca-cert-file ${SSL_CA_CERT} | |||||
tls-cert-file ${SSL_CERT} | |||||
tls-key-file ${SSL_KEY} | |||||
EOF | |||||
fi | |||||
cat ${tmpdir}/redis.conf | |||||
${REDIS_SERVER} ${tmpdir}/redis.conf | |||||
${TEST_PREFIX:-} ./hiredis-test -h 127.0.0.1 -p ${REDIS_PORT} -s ${SOCK_FILE} ${SSL_TEST_ARGS} |
@@ -0,0 +1,56 @@ | |||||
#ifndef _WIN32_HELPER_INCLUDE | |||||
#define _WIN32_HELPER_INCLUDE | |||||
#ifdef _MSC_VER | |||||
#include <winsock2.h> /* for struct timeval */ | |||||
#ifndef inline | |||||
#define inline __inline | |||||
#endif | |||||
#ifndef strcasecmp | |||||
#define strcasecmp stricmp | |||||
#endif | |||||
#ifndef strncasecmp | |||||
#define strncasecmp strnicmp | |||||
#endif | |||||
#ifndef va_copy | |||||
#define va_copy(d,s) ((d) = (s)) | |||||
#endif | |||||
#ifndef snprintf | |||||
#define snprintf c99_snprintf | |||||
__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) | |||||
{ | |||||
int count = -1; | |||||
if (size != 0) | |||||
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); | |||||
if (count == -1) | |||||
count = _vscprintf(format, ap); | |||||
return count; | |||||
} | |||||
__inline int c99_snprintf(char* str, size_t size, const char* format, ...) | |||||
{ | |||||
int count; | |||||
va_list ap; | |||||
va_start(ap, format); | |||||
count = c99_vsnprintf(str, size, format, ap); | |||||
va_end(ap); | |||||
return count; | |||||
} | |||||
#endif | |||||
#endif /* _MSC_VER */ | |||||
#ifdef _WIN32 | |||||
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) | |||||
#endif /* _WIN32 */ | |||||
#endif /* _WIN32_HELPER_INCLUDE */ |