├── .gitattributes
├── .gitignore
├── AddF9card.cmake
├── CMakeLists.txt
├── DotNET
├── fon9api.cs
├── fon9dllName.cs
├── fon9fmkt.cs
├── fon9io.cs
├── fon9rc.cs
├── fon9sv.cs
└── fon9sv_md.cs
├── LICENSE
├── Overview
├── AlNum.md
├── Bitv.md
├── Filing.md
├── Logging.md
├── Manage.md
├── Misc.md
├── Prepare.md
├── Subr.md
├── ThreadTools.md
└── Trie.md
├── README.md
├── TODO.md
├── build
├── cmake
│ ├── Fon9Co.sh
│ ├── build.sh
│ ├── infinity_test.sh
│ ├── t_FileRevRead.sh
│ ├── t_FixReceiver.sh
│ └── unit_test_all.sh
└── vs2015
│ ├── Fon9Co
│ ├── Fon9Co.vcxproj
│ └── Fon9Co.vcxproj.filters
│ ├── _UnitTests
│ ├── AQueue_UT.vcxproj
│ ├── AQueue_UT.vcxproj.filters
│ ├── AuthMgr_UT.vcxproj
│ ├── AuthMgr_UT.vcxproj.filters
│ ├── Base64_UT.vcxproj
│ ├── Base64_UT.vcxproj.filters
│ ├── Bitv_UT.vcxproj
│ ├── Bitv_UT.vcxproj.filters
│ ├── Buffer_UT.vcxproj
│ ├── Buffer_UT.vcxproj.filters
│ ├── CharVector_UT.vcxproj
│ ├── CharVector_UT.vcxproj.filters
│ ├── ConfigLoader_UT.vcxproj
│ ├── ConfigLoader_UT.vcxproj.filters
│ ├── Crypto_UT.vcxproj
│ ├── Crypto_UT.vcxproj.filters
│ ├── Endian_UT.vcxproj
│ ├── Endian_UT.vcxproj.filters
│ ├── FileRevRead_UT.vcxproj
│ ├── FileRevRead_UT.vcxproj.filters
│ ├── File_UT.vcxproj
│ ├── File_UT.vcxproj.filters
│ ├── FixFeeder_UT.vcxproj
│ ├── FixFeeder_UT.vcxproj.filters
│ ├── FixParser_UT.vcxproj
│ ├── FixParser_UT.vcxproj.filters
│ ├── FixReceiver_UT.vcxproj
│ ├── FixReceiver_UT.vcxproj.filters
│ ├── FixRecorder_UT.vcxproj
│ ├── FixRecorder_UT.vcxproj.filters
│ ├── FixSender_UT.vcxproj
│ ├── FixSender_UT.vcxproj.filters
│ ├── FlowControl_UT.vcxproj
│ ├── FlowControl_UT.vcxproj.filters
│ ├── FmktTools_UT.vcxproj
│ ├── FmktTools_UT.vcxproj.filters
│ ├── InnApf_UT.vcxproj
│ ├── InnApf_UT.vcxproj.filters
│ ├── InnDbf_UT.vcxproj
│ ├── InnDbf_UT.vcxproj.filters
│ ├── InnFile_UT.vcxproj
│ ├── InnFile_UT.vcxproj.filters
│ ├── IoDev_UT.vcxproj
│ ├── IoDev_UT.vcxproj.filters
│ ├── IoFixSession_UT.vcxproj
│ ├── IoFixSession_UT.vcxproj.filters
│ ├── LogFile_UT.vcxproj
│ ├── LogFile_UT.vcxproj.filters
│ ├── MemBlock_UT.vcxproj
│ ├── MemBlock_UT.vcxproj.filters
│ ├── ObjSupplier_UT.vcxproj
│ ├── ObjSupplier_UT.vcxproj.filters
│ ├── PackBcd_UT.vcxproj
│ ├── PackBcd_UT.vcxproj.filters
│ ├── PkCont_UT.vcxproj
│ ├── PkCont_UT.vcxproj.filters
│ ├── RcSv_UT.vcxproj
│ ├── RcSv_UT.vcxproj.filters
│ ├── Rc_UT.vcxproj
│ ├── Rc_UT.vcxproj.filters
│ ├── RevPrint_UT.vcxproj
│ ├── RevPrint_UT.vcxproj.filters
│ ├── SchTask_UT.vcxproj
│ ├── SchTask_UT.vcxproj.filters
│ ├── Seed_UT.vcxproj
│ ├── Seed_UT.vcxproj.filters
│ ├── Socket_UT.vcxproj
│ ├── Socket_UT.vcxproj.filters
│ ├── StrTo_UT.vcxproj
│ ├── StrTo_UT.vcxproj.filters
│ ├── StrView_UT.vcxproj
│ ├── StrView_UT.vcxproj.filters
│ ├── Subr_UT.vcxproj
│ ├── Subr_UT.vcxproj.filters
│ ├── Symb_UT.vcxproj
│ ├── Symb_UT.vcxproj.filters
│ ├── ThreadController_UT.vcxproj
│ ├── ThreadController_UT.vcxproj.filters
│ ├── TimeStamp_UT.vcxproj
│ ├── TimeStamp_UT.vcxproj.filters
│ ├── TimedFileName_UT.vcxproj
│ ├── TimedFileName_UT.vcxproj.filters
│ ├── Timer_UT.vcxproj
│ ├── Timer_UT.vcxproj.filters
│ ├── ToStr_UT.vcxproj
│ ├── ToStr_UT.vcxproj.filters
│ ├── Tree_UT.vcxproj
│ ├── Tree_UT.vcxproj.filters
│ ├── Trie_UT.vcxproj
│ └── Trie_UT.vcxproj.filters
│ ├── f9twf
│ ├── f9twfExgMkt_UT.vcxproj
│ ├── f9twfExgMkt_UT.vcxproj.filters
│ ├── f9twf_SymbId_UT.vcxproj
│ ├── f9twf_SymbId_UT.vcxproj.filters
│ ├── libf9twf.vcxproj
│ └── libf9twf.vcxproj.filters
│ ├── f9tws
│ ├── f9twsExgMkt_UT.vcxproj
│ ├── f9twsExgMkt_UT.vcxproj.filters
│ ├── f9twsTrade_UT.vcxproj
│ ├── f9twsTrade_UT.vcxproj.filters
│ ├── libf9tws.vcxproj
│ └── libf9tws.vcxproj.filters
│ ├── fon9.sln
│ ├── libf9extests
│ ├── libf9extests.vcxproj
│ └── libf9extests.vcxproj.filters
│ └── libfon9
│ ├── libfon9.vcxproj
│ └── libfon9.vcxproj.filters
├── ext
├── logvs
│ ├── NanoLog.cpp
│ ├── NanoLog.hpp
│ ├── README.md
│ ├── lock-free-test.txt
│ ├── logvs.cpp
│ ├── makefile
│ ├── mpsc_slist.hpp
│ ├── vs.sh
│ └── vsall.sh
├── sigslot
│ ├── README.md
│ ├── benchmark_f9s.cpp
│ ├── benchmark_f9s.hpp
│ ├── benchmark_f9u.cpp
│ └── benchmark_f9u.hpp
└── yas
│ ├── main.cpp
│ └── run.sh
├── f9extests
├── CMakeLists.txt
├── Config.h
├── ExgMktTester.cpp
├── ExgMktTester.hpp
├── README.md
├── SymbDyTest.cpp
├── SymbIn.cpp
└── SymbIn.hpp
├── f9twf
├── CMakeLists.txt
├── Config.h
├── ExgLineTmpArgs.cpp
├── ExgLineTmpArgs.hpp
├── ExgLineTmpFactory.cpp
├── ExgLineTmpFactory.hpp
├── ExgLineTmpLog.cpp
├── ExgLineTmpLog.hpp
├── ExgLineTmpSession.cpp
├── ExgLineTmpSession.hpp
├── ExgMapFcmId.cpp
├── ExgMapFcmId.hpp
├── ExgMapMgr.cpp
├── ExgMapMgr.hpp
├── ExgMapSessionDn.cpp
├── ExgMapSessionDn.hpp
├── ExgMcChannel.cpp
├── ExgMcChannel.hpp
├── ExgMcChannelTunnel.cpp
├── ExgMcChannelTunnel.hpp
├── ExgMcFmtSS.hpp
├── ExgMcFmtSSToRts.cpp
├── ExgMcFmtSSToRts.hpp
├── ExgMcGroup.cpp
├── ExgMcGroup.hpp
├── ExgMcReceiver.cpp
├── ExgMcReceiver.hpp
├── ExgMcReceiverFactory.cpp
├── ExgMcReceiverFactory.hpp
├── ExgMcToMiConv.cpp
├── ExgMcToMiConv.hpp
├── ExgMdContracts.cpp
├── ExgMdContracts.hpp
├── ExgMdFmt.hpp
├── ExgMdFmtBS.hpp
├── ExgMdFmtBSToRts.cpp
├── ExgMdFmtBSToRts.hpp
├── ExgMdFmtBaseContract.hpp
├── ExgMdFmtBasicInfo.hpp
├── ExgMdFmtBasicInfoToRts.cpp
├── ExgMdFmtBasicInfoToRts.hpp
├── ExgMdFmtClosing.hpp
├── ExgMdFmtClosingToRts.cpp
├── ExgMdFmtClosingToRts.hpp
├── ExgMdFmtHL.hpp
├── ExgMdFmtI060.hpp
├── ExgMdFmtMatch.hpp
├── ExgMdFmtMatchToRts.cpp
├── ExgMdFmtMatchToRts.hpp
├── ExgMdFmtParsers.cpp
├── ExgMdFmtParsers.hpp
├── ExgMdFmtQuoteReq.hpp
├── ExgMdFmtQuoteReqToRts.cpp
├── ExgMdFmtQuoteReqToRts.hpp
├── ExgMdFmtSysInfo.hpp
├── ExgMdFmtSysInfoToRts.cpp
├── ExgMdFmtSysInfoToRts.hpp
├── ExgMdPkReceiver.cpp
├── ExgMdPkReceiver.hpp
├── ExgMdSymbs.cpp
├── ExgMdSymbs.hpp
├── ExgMiReceiver.cpp
├── ExgMiReceiver.hpp
├── ExgMiSystemBase.cpp
├── ExgMiSystemBase.hpp
├── ExgMkt_UT.cpp
├── ExgMrFmt.hpp
├── ExgMrRecover.cpp
├── ExgMrRecover.hpp
├── ExgTmpLinkSys.hpp
├── ExgTmpTradingR1.hpp
├── ExgTmpTradingR7.hpp
├── ExgTmpTradingR9.hpp
├── ExgTmpTypes.cpp
├── ExgTmpTypes.hpp
├── ExgTradingLineMgr.cpp
├── ExgTradingLineMgr.hpp
├── ExgTypes.hpp
├── TwfSymbRef.cpp
├── TwfSymbRef.hpp
├── TwfTickSize.cfg
├── TwfTickSize.cpp
├── TwfTickSize.hpp
└── f9twf_SymbId_UT.cpp
├── f9tws
├── CMakeLists.txt
├── Config.h
├── ExgLineArgs.cpp
├── ExgLineArgs.hpp
├── ExgLineFactory.cpp
├── ExgLineFactory.hpp
├── ExgLineTmp.cpp
├── ExgLineTmp.hpp
├── ExgLineTmpFactory.cpp
├── ExgLineTmpFactory.hpp
├── ExgMdFmt.hpp
├── ExgMdFmt1.hpp
├── ExgMdFmt13.hpp
├── ExgMdFmt13Handler.cpp
├── ExgMdFmt13Handler.hpp
├── ExgMdFmt19.hpp
├── ExgMdFmt19Handler.cpp
├── ExgMdFmt19Handler.hpp
├── ExgMdFmt1Handler.cpp
├── ExgMdFmt1Handler.hpp
├── ExgMdFmt22.hpp
├── ExgMdFmt22Handler.cpp
├── ExgMdFmt22Handler.hpp
├── ExgMdFmt23.hpp
├── ExgMdFmt23Handler.cpp
├── ExgMdFmt23Handler.hpp
├── ExgMdFmt6.hpp
├── ExgMdFmt6Handler.cpp
├── ExgMdFmt6Handler.hpp
├── ExgMdFmt9.hpp
├── ExgMdFmt9Handler.cpp
├── ExgMdFmt9Handler.hpp
├── ExgMdFmtIx.hpp
├── ExgMdFmtIxHandler.cpp
├── ExgMdFmtIxHandler.hpp
├── ExgMdFmtIxNoList.cpp
├── ExgMdFmtIxNoList.hpp
├── ExgMdIndices.cpp
├── ExgMdIndices.hpp
├── ExgMdPkReceiver.cpp
├── ExgMdPkReceiver.hpp
├── ExgMdPlayer.cpp
├── ExgMdReceiverFactory.cpp
├── ExgMdReceiverFactory.hpp
├── ExgMdReceiverSession.cpp
├── ExgMdReceiverSession.hpp
├── ExgMdSymbs.cpp
├── ExgMdSymbs.hpp
├── ExgMdSystem.cpp
├── ExgMdSystem.hpp
├── ExgMdSystemBase.cpp
├── ExgMdSystemBase.hpp
├── ExgMkt_UT.cpp
├── ExgTradingLineFix.cpp
├── ExgTradingLineFix.hpp
├── ExgTradingLineFixFactory.cpp
├── ExgTradingLineFixFactory.hpp
├── ExgTradingLineMgr.cpp
├── ExgTradingLineMgr.hpp
├── ExgTypes.hpp
├── README.md
├── TwsTools.cpp
├── TwsTools.hpp
├── TwsTypes.h
└── f9twsTrade_UT.cpp
├── fon9
├── AQueue.hpp
├── AQueue_UT.cpp
├── Appender.cpp
├── Appender.hpp
├── Archive.hpp
├── Assert.c
├── Assert.h
├── Base64.cpp
├── Base64.hpp
├── Base64_UT.cpp
├── Bitv.h
├── BitvArchive.hpp
├── BitvDecode.cpp
├── BitvDecode.hpp
├── BitvEncode.cpp
├── BitvEncode.hpp
├── BitvFixedInt.hpp
├── Bitv_UT.cpp
├── Blob.c
├── Blob.h
├── ByteVector.cpp
├── ByteVector.hpp
├── CMakeLists.txt
├── CStrView.h
├── CTools.c
├── CTools.h
├── CharAry.hpp
├── CharAryL.hpp
├── CharVector.hpp
├── CharVector_UT.cpp
├── CmdArgs.cpp
├── CmdArgs.hpp
├── Comparable.hpp
├── ConfigFileBinder.cpp
├── ConfigFileBinder.hpp
├── ConfigLoader.cpp
├── ConfigLoader.hpp
├── ConfigLoader_UT.cpp
├── ConfigParser.cpp
├── ConfigParser.hpp
├── ConfigUtils.cpp
├── ConfigUtils.hpp
├── ConsoleIO.cpp
├── ConsoleIO.h
├── CountDownLatch.cpp
├── CountDownLatch.hpp
├── CtrlBreakHandler.c
├── CtrlBreakHandler.h
├── CyclicBarrier.cpp
├── CyclicBarrier.hpp
├── DecBase.cpp
├── DecBase.hpp
├── Decimal.hpp
├── DefaultThreadPool.cpp
├── DefaultThreadPool.hpp
├── DllHandle.cpp
├── DllHandle.hpp
├── DummyMutex.hpp
├── DyObj.hpp
├── Endian.hpp
├── Endian_UT.cpp
├── ErrC.cpp
├── ErrC.hpp
├── Exception.hpp
├── F9cardDevel.h
├── Fdr.hpp
├── FdrNotify.cpp
├── FdrNotify.hpp
├── File.cpp
├── File.hpp
├── FileAppender.cpp
├── FileAppender.hpp
├── FilePath.cpp
├── FilePath.hpp
├── FileReadAll.cpp
├── FileReadAll.hpp
├── FileRevRead.cpp
├── FileRevRead.hpp
├── FileRevRead_UT.cpp
├── File_UT.cpp
├── FlowControlCalc.cpp
├── FlowControlCalc.hpp
├── FlowControl_UT.cpp
├── FlowCounter.cpp
├── FlowCounter.hpp
├── FmtDef.cpp
├── FmtDef.hpp
├── FwdPrint.hpp
├── HistoryArray.hpp
├── HostId.cpp
├── HostId.hpp
├── InnApf.cpp
├── InnApf.hpp
├── InnApf_UT.cpp
├── InnDbf.cpp
├── InnDbf.hpp
├── InnDbfRoom.hpp
├── InnDbfTable.hpp
├── InnDbf_UT.cpp
├── InnFile.cpp
├── InnFile.hpp
├── InnFile_UT.cpp
├── InnStream.cpp
├── InnStream.hpp
├── InnSyncKey.hpp
├── InnSyncer.cpp
├── InnSyncer.hpp
├── InnSyncerFile.cpp
├── InnSyncerFile.hpp
├── IntSel.hpp
├── LevelArray.hpp
├── Log.cpp
├── Log.hpp
├── LogFile.cpp
├── LogFile.hpp
├── LogFile_UT.cpp
├── MessageQueue.hpp
├── MustLock.hpp
├── Named.cpp
├── Named.hpp
├── NamedIx.hpp
├── ObjPool.hpp
├── ObjSupplier.cpp
├── ObjSupplier.hpp
├── ObjSupplier_UT.cpp
├── Outcome.cpp
├── Outcome.hpp
├── PackBcd.hpp
├── PackBcd_UT.cpp
├── PassKey.cpp
├── PassKey.hpp
├── PkCont.cpp
├── PkCont.hpp
├── PkCont_UT.cpp
├── PkReceiver.cpp
├── PkReceiver.hpp
├── Random.cpp
├── Random.hpp
├── RevFormat.cpp
├── RevFormat.hpp
├── RevPrint.hpp
├── RevPrint_UT.cpp
├── RevPut.hpp
├── SchTask.cpp
├── SchTask.hpp
├── SchTask_UT.cpp
├── SimpleFactory.cpp
├── SimpleFactory.hpp
├── SinglyLinkedList.hpp
├── SleepPolicy.hpp
├── SortedVector.hpp
├── SpinMutex.hpp
├── StaticPtr.hpp
├── StrPicAux.hpp
├── StrTo.cpp
├── StrTo.hpp
├── StrTo_UT.cpp
├── StrTools.cpp
├── StrTools.hpp
├── StrView.hpp
├── StrView_UT.cpp
├── StrVref.hpp
├── Subr.hpp
├── Subr_UT.cpp
├── TestTools.hpp
├── TestTools_MemUsed.hpp
├── ThreadController.hpp
├── ThreadController_UT.cpp
├── ThreadId.cpp
├── ThreadId.hpp
├── ThreadTools.cpp
├── ThreadTools.hpp
├── TimeInterval.cpp
├── TimeInterval.hpp
├── TimeStamp.cpp
├── TimeStamp.hpp
├── TimeStamp_UT.cpp
├── TimedFileName.cpp
├── TimedFileName.hpp
├── TimedFileName_UT.cpp
├── Timer.cpp
├── Timer.hpp
├── Timer_UT.cpp
├── ToStr.cpp
├── ToStr.hpp
├── ToStrFmt.cpp
├── ToStrFmt.hpp
├── ToStr_UT.cpp
├── Tools.cpp
├── Tools.hpp
├── Trie.hpp
├── Trie_UT.cpp
├── TsAppend.cpp
├── TsAppend.hpp
├── TsReceiver.cpp
├── TsReceiver.hpp
├── TypeName.hpp
├── Unaligned.hpp
├── Utility.hpp
├── WaitPolicy.hpp
├── Worker.hpp
├── auth
│ ├── AuthBase.h
│ ├── AuthBase.hpp
│ ├── AuthMgr.cpp
│ ├── AuthMgr.hpp
│ ├── AuthMgr_UT.cpp
│ ├── PassIdMgr.cpp
│ ├── PassIdMgr.hpp
│ ├── PoDupLogon.cpp
│ ├── PoDupLogon.hpp
│ ├── PolicyAcl.cpp
│ ├── PolicyAcl.hpp
│ ├── PolicyAgent.hpp
│ ├── PolicyMaster.cpp
│ ├── PolicyMaster.hpp
│ ├── PolicySocketFrom.cpp
│ ├── PolicySocketFrom.hpp
│ ├── PolicyTable.cpp
│ ├── PolicyTable.hpp
│ ├── PolicyTree.cpp
│ ├── PolicyTree.hpp
│ ├── RoleMgr.cpp
│ ├── RoleMgr.hpp
│ ├── SaslClient.cpp
│ ├── SaslClient.hpp
│ ├── SaslScram.hpp
│ ├── SaslScramServer.cpp
│ ├── SaslScramServer.hpp
│ ├── SaslScramSha256.cpp
│ ├── SaslScramSha256.hpp
│ ├── SaslScramSha256Client.cpp
│ ├── SaslScramSha256Client.hpp
│ ├── SaslScramSha256Server.cpp
│ ├── SaslScramSha256Server.hpp
│ ├── UserMgr.cpp
│ └── UserMgr.hpp
├── buffer
│ ├── BufferList.cpp
│ ├── BufferList.hpp
│ ├── BufferListBuilder.hpp
│ ├── BufferNode.cpp
│ ├── BufferNode.hpp
│ ├── BufferNodeWaiter.cpp
│ ├── BufferNodeWaiter.hpp
│ ├── Buffer_UT.cpp
│ ├── DcQueue.cpp
│ ├── DcQueue.hpp
│ ├── DcQueueList.cpp
│ ├── DcQueueList.hpp
│ ├── FwdBuffer.hpp
│ ├── FwdBufferList.hpp
│ ├── MemBlock.cpp
│ ├── MemBlock.hpp
│ ├── MemBlockImpl.hpp
│ ├── MemBlock_UT.cpp
│ ├── README.md
│ ├── RevBuffer.cpp
│ ├── RevBuffer.hpp
│ ├── RevBufferList.cpp
│ └── RevBufferList.hpp
├── crypto
│ ├── CryptoTools.hpp
│ ├── Crypto_UT.cpp
│ ├── Sha1.cpp
│ ├── Sha1.hpp
│ ├── Sha256.cpp
│ └── Sha256.hpp
├── fix
│ ├── FixAdminDef.hpp
│ ├── FixAdminMsg.cpp
│ ├── FixAdminMsg.hpp
│ ├── FixApDef.hpp
│ ├── FixBase.cpp
│ ├── FixBase.hpp
│ ├── FixBuilder.cpp
│ ├── FixBuilder.hpp
│ ├── FixBusinessReject.cpp
│ ├── FixBusinessReject.hpp
│ ├── FixCompID.cpp
│ ├── FixCompID.hpp
│ ├── FixConfig.cpp
│ ├── FixConfig.hpp
│ ├── FixFeeder.cpp
│ ├── FixFeeder.hpp
│ ├── FixFeeder_UT.cpp
│ ├── FixParser.cpp
│ ├── FixParser.hpp
│ ├── FixParser_UT.cpp
│ ├── FixReceiver.cpp
│ ├── FixReceiver.hpp
│ ├── FixReceiver_UT.cpp
│ ├── FixReceiver_UT_Case.txt
│ ├── FixReceiver_UT_Result.txt
│ ├── FixRecorder.cpp
│ ├── FixRecorder.hpp
│ ├── FixRecorder_Searcher.cpp
│ ├── FixRecorder_Searcher.hpp
│ ├── FixRecorder_UT.cpp
│ ├── FixSender.cpp
│ ├── FixSender.hpp
│ ├── FixSender_UT.cpp
│ ├── FixSession.cpp
│ ├── FixSession.hpp
│ ├── IoFixSender.cpp
│ ├── IoFixSender.hpp
│ ├── IoFixSession.cpp
│ ├── IoFixSession.hpp
│ ├── IoFixSession_UT.cpp
│ └── README.md
├── fmkt
│ ├── FmdRtsPackType.h
│ ├── FmdRtsPackType.txt
│ ├── FmdTypes.h
│ ├── FmdTypes.hpp
│ ├── FmktTools.cpp
│ ├── FmktTools.hpp
│ ├── FmktTools_UT.cpp
│ ├── FmktTypes.h
│ ├── FmktTypes.hpp
│ ├── MdRtStream.cpp
│ ├── MdRtStream.hpp
│ ├── MdRtStreamInn.cpp
│ ├── MdRtStreamInn.hpp
│ ├── MdRtsTypes.cpp
│ ├── MdRtsTypes.hpp
│ ├── MdSymbs.cpp
│ ├── MdSymbs.hpp
│ ├── MdSystem.cpp
│ ├── MdSystem.hpp
│ ├── README.md
│ ├── Symb.cpp
│ ├── Symb.hpp
│ ├── SymbBS.cpp
│ ├── SymbBS.hpp
│ ├── SymbBSData.hpp
│ ├── SymbBreakSt.cpp
│ ├── SymbBreakSt.hpp
│ ├── SymbDeal.cpp
│ ├── SymbDeal.hpp
│ ├── SymbDealData.hpp
│ ├── SymbDy.cpp
│ ├── SymbDy.hpp
│ ├── SymbDynBand.cpp
│ ├── SymbDynBand.hpp
│ ├── SymbFuoClosing.cpp
│ ├── SymbFuoClosing.hpp
│ ├── SymbQuoteReq.cpp
│ ├── SymbQuoteReq.hpp
│ ├── SymbRef.cpp
│ ├── SymbRef.hpp
│ ├── SymbTabNames.h
│ ├── SymbTimePri.cpp
│ ├── SymbTimePri.hpp
│ ├── SymbTree.cpp
│ ├── SymbTree.hpp
│ ├── SymbTwa.cpp
│ ├── SymbTwa.hpp
│ ├── SymbTwaBase.cpp
│ ├── SymbTwaBase.hpp
│ ├── SymbTwf.cpp
│ ├── SymbTwf.hpp
│ ├── SymbTwfBase.cpp
│ ├── SymbTwfBase.hpp
│ ├── SymbTws.cpp
│ ├── SymbTws.hpp
│ ├── SymbTwsBase.cpp
│ ├── SymbTwsBase.hpp
│ ├── Symb_UT.cpp
│ ├── TradingLine.cpp
│ ├── TradingLine.hpp
│ ├── TradingLineGroup.cpp
│ ├── TradingLineGroup.hpp
│ ├── TradingLineHelper1.cpp
│ ├── TradingLineHelper1.hpp
│ ├── TradingLineManagerSeed.cpp
│ ├── TradingLineManagerSeed.hpp
│ ├── TradingRequest.cpp
│ ├── TradingRequest.hpp
│ └── TwExgMdTime.hpp
├── framework
│ ├── Fon9CoRun.cpp
│ ├── Fon9Co_main.cpp
│ ├── Framework.cpp
│ ├── Framework.hpp
│ ├── FrameworkFlag.cpp
│ ├── FrameworkFlag.hpp
│ ├── IoFactory.cpp
│ ├── IoFactory.hpp
│ ├── IoFactoryDgram.cpp
│ ├── IoFactoryFileIO.cpp
│ ├── IoFactoryTcpClient.cpp
│ ├── IoFactoryTcpServer.cpp
│ ├── IoFactoryTcpServerAB.cpp
│ ├── IoManager.cpp
│ ├── IoManager.hpp
│ ├── IoManagerTree.cpp
│ ├── IoManagerTree.hpp
│ ├── NamedIoManager.cpp
│ ├── SeedImporter.cpp
│ ├── SeedSession.cpp
│ ├── SeedSession.hpp
│ ├── SessionFactoryConfigWithAuthMgr.cpp
│ └── SessionFactoryConfigWithAuthMgr.hpp
├── intrusive_ptr.hpp
├── intrusive_ref_counter.hpp
├── io
│ ├── Device.cpp
│ ├── Device.hpp
│ ├── DeviceAsyncOp.hpp
│ ├── DeviceParseConfig.hpp
│ ├── DeviceRecvEvent.hpp
│ ├── DeviceStartSend.hpp
│ ├── DgramBase.cpp
│ ├── DgramBase.hpp
│ ├── FdrDgram.cpp
│ ├── FdrDgram.hpp
│ ├── FdrService.cpp
│ ├── FdrService.hpp
│ ├── FdrServiceEpoll.cpp
│ ├── FdrServiceEpoll.hpp
│ ├── FdrSocket.cpp
│ ├── FdrSocket.hpp
│ ├── FdrSocketClient.cpp
│ ├── FdrSocketClient.hpp
│ ├── FdrTcpClient.cpp
│ ├── FdrTcpClient.hpp
│ ├── FdrTcpServer.cpp
│ ├── FdrTcpServer.hpp
│ ├── FileIO.cpp
│ ├── FileIO.hpp
│ ├── IoBase.cpp
│ ├── IoBase.hpp
│ ├── IoDev_UT.cpp
│ ├── IoServiceArgs.cpp
│ ├── IoServiceArgs.hpp
│ ├── IoState.h
│ ├── Manager.cpp
│ ├── Manager.hpp
│ ├── README.md
│ ├── RecvBuffer.cpp
│ ├── RecvBuffer.hpp
│ ├── SendBuffer.cpp
│ ├── SendBuffer.hpp
│ ├── Server.cpp
│ ├── Server.hpp
│ ├── Session.cpp
│ ├── Session.hpp
│ ├── SimpleManager.hpp
│ ├── Socket.cpp
│ ├── Socket.hpp
│ ├── SocketAddress.cpp
│ ├── SocketAddress.hpp
│ ├── SocketAddressDN.cpp
│ ├── SocketAddressDN.hpp
│ ├── SocketClientConfig.cpp
│ ├── SocketClientConfig.hpp
│ ├── SocketClientDevice.cpp
│ ├── SocketClientDevice.hpp
│ ├── SocketConfig.cpp
│ ├── SocketConfig.hpp
│ ├── SocketServer.cpp
│ ├── SocketServer.hpp
│ ├── Socket_UT.cpp
│ ├── TcpClientBase.cpp
│ ├── TcpClientBase.hpp
│ ├── TcpServerBase.cpp
│ ├── TcpServerBase.hpp
│ ├── TestDevice.hpp
│ └── win
│ │ ├── IocpDgram.cpp
│ │ ├── IocpDgram.hpp
│ │ ├── IocpService.cpp
│ │ ├── IocpService.hpp
│ │ ├── IocpSocket.cpp
│ │ ├── IocpSocket.hpp
│ │ ├── IocpSocketClient.cpp
│ │ ├── IocpSocketClient.hpp
│ │ ├── IocpTcpClient.cpp
│ │ ├── IocpTcpClient.hpp
│ │ ├── IocpTcpServer.cpp
│ │ └── IocpTcpServer.hpp
├── rc
│ ├── README.md
│ ├── Rc.cpp
│ ├── Rc.h
│ ├── Rc.hpp
│ ├── RcClientApi.cpp
│ ├── RcClientApi.h
│ ├── RcClientSession.cpp
│ ├── RcClientSession.hpp
│ ├── RcFuncConn.cpp
│ ├── RcFuncConn.hpp
│ ├── RcFuncConnClient.cpp
│ ├── RcFuncConnServer.cpp
│ ├── RcFuncConnServer.hpp
│ ├── RcMdRtsDecoder.cpp
│ ├── RcMdRtsDecoder.h
│ ├── RcMdRtsDecoder.hpp
│ ├── RcSeedVisitor.cpp
│ ├── RcSeedVisitor.h
│ ├── RcSeedVisitor.hpp
│ ├── RcSeedVisitorClient.cpp
│ ├── RcSeedVisitorClient.hpp
│ ├── RcSeedVisitorClientCAPI.cpp
│ ├── RcSeedVisitorServer.cpp
│ ├── RcSeedVisitorServer.hpp
│ ├── RcSession.cpp
│ ├── RcSession.hpp
│ ├── RcSvStreamDecoder.cpp
│ ├── RcSvStreamDecoder.hpp
│ ├── RcSv_UT.cpp
│ ├── RcSvc.cpp
│ ├── RcSvc.hpp
│ ├── RcSvcAck.cpp
│ ├── RcSvcAck.hpp
│ ├── RcSvcReq.cpp
│ ├── RcSvcReq.hpp
│ ├── RcSvcReqSeed.cpp
│ ├── RcSvcReqSubr.cpp
│ ├── RcSvsTicket.cpp
│ ├── RcSvsTicket.hpp
│ └── Rc_UT.cpp
├── seed
│ ├── CloneTree.cpp
│ ├── CloneTree.hpp
│ ├── ConfigGridView.cpp
│ ├── ConfigGridView.hpp
│ ├── Field.cpp
│ ├── Field.hpp
│ ├── FieldBytes.cpp
│ ├── FieldBytes.hpp
│ ├── FieldChars.cpp
│ ├── FieldChars.hpp
│ ├── FieldCharsL.cpp
│ ├── FieldCharsL.hpp
│ ├── FieldDecimal.hpp
│ ├── FieldDyBlob.cpp
│ ├── FieldDyBlob.hpp
│ ├── FieldInt.hpp
│ ├── FieldMaker.cpp
│ ├── FieldMaker.hpp
│ ├── FieldSchCfgStr.cpp
│ ├── FieldSchCfgStr.hpp
│ ├── FieldString.hpp
│ ├── FieldTimeStamp.hpp
│ ├── FieldType.h
│ ├── FieldValueFmt.hpp
│ ├── FileImpTree.cpp
│ ├── FileImpTree.hpp
│ ├── Layout.cpp
│ ├── Layout.hpp
│ ├── MaConfigTree.cpp
│ ├── MaConfigTree.hpp
│ ├── MaTree.cpp
│ ├── MaTree.hpp
│ ├── NamedPark.cpp
│ ├── NamedPark.hpp
│ ├── Plugins.cpp
│ ├── Plugins.hpp
│ ├── PluginsMgr.cpp
│ ├── PluginsMgr.hpp
│ ├── PodOp.cpp
│ ├── PodOp.hpp
│ ├── README.md
│ ├── Raw.cpp
│ ├── Raw.hpp
│ ├── RawRd.hpp
│ ├── RawWr.hpp
│ ├── SeedAcl.cpp
│ ├── SeedAcl.hpp
│ ├── SeedAclTree.cpp
│ ├── SeedBase.cpp
│ ├── SeedBase.hpp
│ ├── SeedFairy.cpp
│ ├── SeedFairy.hpp
│ ├── SeedSearcher.cpp
│ ├── SeedSearcher.hpp
│ ├── SeedSubr.cpp
│ ├── SeedSubr.hpp
│ ├── SeedVisitor.cpp
│ ├── SeedVisitor.hpp
│ ├── Seed_UT.cpp
│ ├── SysEnv.cpp
│ ├── SysEnv.hpp
│ ├── Tab.cpp
│ ├── Tab.hpp
│ ├── TabTreeOp.cpp
│ ├── TabTreeOp.hpp
│ ├── Tree.cpp
│ ├── Tree.hpp
│ ├── TreeLockContainerT.hpp
│ ├── TreeOp.cpp
│ ├── TreeOp.hpp
│ └── Tree_UT.cpp
├── sys
│ ├── Config.h
│ ├── Config.hpp
│ ├── FilePOSIX.hpp
│ ├── FileWin32.hpp
│ ├── OnWindowsMainExit.cpp
│ └── OnWindowsMainExit.hpp
└── web
│ ├── HtmlEncoder.cpp
│ ├── HtmlEncoder.hpp
│ ├── HttpDate.cpp
│ ├── HttpDate.hpp
│ ├── HttpHandler.cpp
│ ├── HttpHandler.hpp
│ ├── HttpHandlerStatic.cpp
│ ├── HttpHandlerStatic.hpp
│ ├── HttpMessage.cpp
│ ├── HttpMessage.hpp
│ ├── HttpParser.cpp
│ ├── HttpParser.hpp
│ ├── HttpPlugins.cpp
│ ├── HttpSession.cpp
│ ├── HttpSession.hpp
│ ├── HttpStatic.cfg
│ ├── StartupHttpMa.md
│ ├── UrlCodec.cpp
│ ├── UrlCodec.hpp
│ ├── WebSocket.cpp
│ ├── WebSocket.hpp
│ ├── WebSocketAuther.cpp
│ ├── WebSocketAuther.hpp
│ ├── WsSeedVisitor.cpp
│ ├── WsSeedVisitor.hpp
│ └── ma
│ ├── crypto.js
│ ├── fon9.css
│ ├── fon9chgpass.html
│ ├── fon9ma.html
│ ├── fon9seed.html
│ ├── fon9signon.html
│ ├── gv.css
│ ├── gvTable.js
│ ├── logo-40.png
│ ├── sasl-scram-ut.html
│ ├── sasl-scram.js
│ ├── sasl-ws-ut.html
│ ├── sasl-ws.js
│ ├── utils-seed.js
│ └── utils.js
├── make_proj_verinfo.bat
├── make_proj_verinfo.sh
└── make_static_o.sh
/AddF9card.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # 在 CMakeLists.txt, 檢查是否有支援 f9card 的 source code.
3 | # 要在 add_subdirectory(fon9) 之前使用 include() 加入此檔,
4 | # 避免在多個路徑下皆有 f9/ 造成 libf9_s 重複定義;
5 | #
6 | # include(fon9/AddF9card.cmake)
7 | # add_subdirectory(fon9)
8 | #
9 | if(NOT DEFINED F9PATH)
10 | set(F9PATH "${CMAKE_CURRENT_SOURCE_DIR}/f9")
11 | if(EXISTS "${F9PATH}/net" AND IS_DIRECTORY "${F9PATH}/net")
12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DF9CARD")
13 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DF9CARD")
14 | set(f9_s_lib "f9_s")
15 | add_subdirectory(f9)
16 | else()
17 | unset(F9PATH)
18 | endif()
19 | endif()
20 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.6)
2 | project(fon9)
3 |
4 | if(NOT CMAKE_BUILD_TYPE)
5 | set(CMAKE_BUILD_TYPE "Release")
6 | endif()
7 |
8 | set(CXX_FLAGS
9 | -g
10 | -Wall
11 | -Wextra
12 | -Wconversion
13 | -Wold-style-cast
14 | -Woverloaded-virtual
15 | -Wpointer-arith
16 | -Wshadow
17 | -Wwrite-strings
18 | -fexec-charset=UTF-8
19 | -std=c++11
20 | ${FON9_CXX_FLAGS}
21 | )
22 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
23 |
24 | set(C_FLAGS
25 | -g
26 | -Wall
27 | -Wextra
28 | -Wconversion
29 | -Wpointer-arith
30 | -Wshadow
31 | -Wwrite-strings
32 | -fexec-charset=UTF-8
33 | ${FON9_C_FLAGS}
34 | )
35 | string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}")
36 | # ---
37 | include(AddF9card.cmake)
38 | # ---
39 | include_directories(.)
40 |
41 | add_subdirectory(fon9)
42 |
43 | if(CMAKE_FON9_BUILD_UNIT_TEST)
44 | add_subdirectory(f9extests)
45 | endif()
46 |
47 | add_subdirectory(f9tws)
48 | add_subdirectory(f9twf)
49 |
--------------------------------------------------------------------------------
/DotNET/fon9dllName.cs:
--------------------------------------------------------------------------------
1 | namespace fon9
2 | {
3 | static class DotNetApi
4 | {
5 | public const string kDllName = "libfon9.dll";
6 | }
7 | }
--------------------------------------------------------------------------------
/DotNET/fon9io.cs:
--------------------------------------------------------------------------------
1 | namespace f9io
2 | {
3 | public enum State
4 | {
5 | /// 初始化尚未完成: Device 建構之後的初始狀態.
6 | Initializing,
7 | /// 建構 Device 的人必須主動呼叫 Device::Initialize() 才會進入此狀態.
8 | Initialized,
9 |
10 | /// Device::OpImpl_Open() 因設定錯誤的開啟失敗。
11 | /// 無法使用相同 cfgstr 再次開啟.
12 | ConfigError,
13 | /// 開啟中: 開啟尚未完成.
14 | /// 若開啟完成, 則進入底下3種可能的狀態, 視不同的 Device Style 而定:
15 | /// - WaitingLinkIn
16 | /// - Linking
17 | /// - Listening
18 | Opening,
19 |
20 | /// 連入等候中: 例如一個 USB port, 正在等候 USB 設備的插入.
21 | WaitingLinkIn,
22 | /// 連線建立中: 例如 TcpClient 呼叫了 connect().
23 | Linking,
24 | /// 連線建立失敗: 例如 TcpClient 呼叫 connect() 之後沒有連線成功.
25 | LinkError,
26 | /// 連線成功: 可以開始收送資料.
27 | /// - WaitingLinkIn, Linking 之後, 連線成功的狀態.
28 | LinkReady,
29 | /// 連線中斷.
30 | /// - **LinkReady 之後** , 連線中斷了!
31 | LinkBroken,
32 |
33 | /// Listening(例如: TcpServer)
34 | Listening,
35 | /// Listening之後被中斷: reset 網卡/IP?
36 | ListenBroken,
37 |
38 | /// 逗留中, 等資料送完後關閉.
39 | Lingering,
40 | /// 關閉中.
41 | Closing,
42 | /// 已關閉.
43 | Closed,
44 |
45 | /// 即將解構, Device 已不可再使用!
46 | /// 當收到此狀態, 您應該盡快將 Device 釋放.
47 | Disposing,
48 | /// 在 Device::~Device() 最後的解構狀態.
49 | Destructing,
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Overview/Prepare.md:
--------------------------------------------------------------------------------
1 | fon9 library - prepare
2 | =======================
3 |
4 | ## 主要開發工具及版本
5 | * Windows: VS 2015
6 | * `./build/vs2015/fon9.sln`
7 | * Linux:
8 | * cmake version 3.5.1
9 | * gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
10 | * `./build/cmake/build.sh`
11 | * 開啟 compiler 全部的警告訊息:警告訊息的重要性,相信不用再提醒了。
12 | * 警告訊息 -- 零容忍。
13 |
14 | ## 預設路徑結構
15 | ```
16 | ~/devel/ 我的開發環境根目錄
17 | |-- external/ third-party libraries
18 | |
19 | |-- output/fon9/ libfon9 的輸出路徑,「輸出路徑」移到原始程式路徑之外,可以更容易「乾淨備份」。
20 | | |-- 64/Release/ 預設 Windows 的 fon9.sln 輸出路徑
21 | | \-- release/fon9/ 預設 Linux 輸出路徑
22 | |
23 | \-- fon9/
24 | |-- fon9/ header(.hpp & .h) & source(.cpp & .c) 放在一起,更容易找到所需的檔案。
25 | | \-- sys/ 平台、Compiler 相關
26 | |
27 | |-- ext/ 配合 third-party 寫的測試或 benchmark
28 | | |-- sigslot/ signal-slot-benchmarks
29 | | \-- logvs/ logging 測試與比較
30 | |
31 | \-- build/
32 | |-- cmake/ build shell for cmake
33 | \-- vs2015/ VS2015 project & solution files
34 | ```
35 |
--------------------------------------------------------------------------------
/build/cmake/Fon9Co.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # fon9/build/cmake/Fon9Co.sh
4 | #
5 |
6 | ulimit -c unlimited
7 |
8 | set -x
9 | set -e
10 |
11 | ~/devel/output/fon9/release/fon9/Fon9Co --workdir ~/devel/output/fon9
12 |
--------------------------------------------------------------------------------
/build/cmake/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # fon9/build/cmake/build.sh
4 | #
5 |
6 | fon9path=`pwd`"$0"
7 | fon9path="${fon9path%/*}"
8 | fon9path="${fon9path%/*}"
9 | fon9path="${fon9path%/*}"
10 | develpath="${fon9path%/*}"
11 |
12 | set -x
13 |
14 | SOURCE_DIR=${fon9path}
15 | BUILD_DIR=${BUILD_DIR:-${develpath}/output/fon9}
16 | BUILD_TYPE=${BUILD_TYPE:-release}
17 | INSTALL_DIR=${INSTALL_DIR:-${develpath}/${BUILD_TYPE}}
18 | FON9_BUILD_UNIT_TEST=${FON9_BUILD_UNIT_TEST:-1}
19 |
20 | mkdir -p $BUILD_DIR/$BUILD_TYPE \
21 | && cd $BUILD_DIR/$BUILD_TYPE \
22 | && cmake \
23 | -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
24 | -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
25 | -DCMAKE_FON9_BUILD_UNIT_TEST=$FON9_BUILD_UNIT_TEST \
26 | $SOURCE_DIR \
27 | && make $*
28 |
--------------------------------------------------------------------------------
/build/cmake/infinity_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # fon9/build/cmake/infinity_test.sh
4 | #
5 |
6 | ulimit -c unlimited
7 |
8 | set -x
9 | set -e
10 |
11 | while true
12 | do
13 | $*
14 | done
15 |
--------------------------------------------------------------------------------
/build/cmake/t_FileRevRead.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # fon9/build/cmake/t_FileRevRead.sh
4 | #
5 |
6 | fon9path=`pwd`"$0"
7 | fon9path="${fon9path%/*}"
8 | fon9path="${fon9path%/*}"
9 | fon9path="${fon9path%/*}"
10 | develpath="${fon9path%/*}"
11 | BUILD_DIR=${BUILD_DIR:-${develpath}/output/fon9}
12 | BUILD_TYPE=${BUILD_TYPE:-release}
13 |
14 | ulimit -c unlimited
15 |
16 | set -x
17 | set -e
18 |
19 | OUTPUT_DIR=${OUTPUT_DIR:-${BUILD_DIR}/${BUILD_TYPE}/fon9}
20 |
21 | $OUTPUT_DIR/FileRevRead_UT $1 outf
22 | tac $1 > outx
23 | diff outf outx
24 |
25 | if [ $? -eq 0 ]
26 | then
27 | echo "[OK ] FileRevRead_UT."
28 | else
29 | echo "[ERROR] FileRevRead_UT."
30 | fi
31 |
--------------------------------------------------------------------------------
/build/cmake/t_FixReceiver.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # fon9/build/cmake/t_FixReceiver.sh
4 | #
5 |
6 | fon9path=`pwd`"$0"
7 | fon9path="${fon9path%/*}"
8 | fon9path="${fon9path%/*}"
9 | fon9path="${fon9path%/*}"
10 | develpath="${fon9path%/*}"
11 | BUILD_DIR=${BUILD_DIR:-${develpath}/output/fon9}
12 | BUILD_TYPE=${BUILD_TYPE:-release}
13 |
14 | ulimit -c unlimited
15 |
16 | set -x
17 | set -e
18 |
19 | OUTPUT_DIR=${OUTPUT_DIR:-${BUILD_DIR}/${BUILD_TYPE}/fon9}
20 |
21 | rm -f fix.log
22 | $OUTPUT_DIR/FixReceiver_UT ./fix.log ../../fon9/fix/FixReceiver_UT_Case.txt
23 |
24 | # 移除紀錄的 timestamp.
25 | sed -E 's/(^. )[0-9]*\.[0-9]* /\1/' -i fix.log
26 |
27 | # 移除送出訊息的 52=SendingTime, 及 10=CheckSum: 因為每次測試這2個欄位都不會相同.
28 | sed -E 's/(^S .*52=)[0-9]*-[0-9]*:[0-9]*:[0-9]*\.[0-9]*(.*)10=[0-9]*.$/\1\2/' -i fix.log
29 |
30 | diff fix.log ../../fon9/fix/FixReceiver_UT_Result.txt
31 | if [ $? -eq 0 ]
32 | then
33 | echo "[OK ] FixReceiver_UT."
34 | else
35 | echo "[ERROR] FixReceiver_UT."
36 | fi
37 |
--------------------------------------------------------------------------------
/build/vs2015/Fon9Co/Fon9Co.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {39a94389-0e79-4814-aebc-c95df75e1e14}
14 |
15 |
16 |
17 |
18 | Source Files
19 |
20 |
21 | Source Files
22 |
23 |
24 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/AQueue_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/AuthMgr_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Base64_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Buffer_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/CharVector_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/ConfigLoader_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Crypto_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Endian_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FileRevRead_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/File_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FixFeeder_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FixParser_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FixReceiver_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FixRecorder_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FixSender_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FlowControl_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/FmktTools_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Header Files
16 |
17 |
18 |
19 |
20 | Source Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/InnApf_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 | Header Files
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/InnDbf_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/InnFile_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/IoDev_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/IoFixSession_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/LogFile_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/MemBlock_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/ObjSupplier_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Header Files
16 |
17 |
18 |
19 |
20 | Source Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/PackBcd_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/PkCont_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/RcSv_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Rc_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/RevPrint_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Header Files
16 |
17 |
18 | Header Files
19 |
20 |
21 | Header Files
22 |
23 |
24 | Header Files
25 |
26 |
27 |
28 |
29 | Source Files
30 |
31 |
32 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/SchTask_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Seed_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Socket_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/StrTo_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Header Files
16 |
17 |
18 | Header Files
19 |
20 |
21 |
22 |
23 | Source Files
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Symb_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/ThreadController_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 | Header Files
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/TimeStamp_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 | Header Files
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/TimedFileName_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Timer_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/ToStr_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Tree_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/_UnitTests/Trie_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
19 |
20 | Header Files
21 |
22 |
23 | Header Files
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/vs2015/f9twf/f9twfExgMkt_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/f9twf/f9twf_SymbId_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/f9tws/f9twsExgMkt_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 |
--------------------------------------------------------------------------------
/build/vs2015/f9tws/f9twsTrade_UT.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 |
14 |
15 | Source Files
16 |
17 |
18 | Source Files
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ext/logvs/makefile:
--------------------------------------------------------------------------------
1 | INC=-I../../../external/mini-async-log/include -I../../../external/spdlog/include -I../..
2 | LIB=-L../../../external/mini-async-log -lmini_async_log -L../../../output/fon9/release/fon9 -lfon9_s
3 |
4 | all:
5 | g++ -D NDEBUG -g -O3 -std=c++11 -pthread logvs.cpp NanoLog.cpp $(INC) $(LIB) -o logvs
6 |
--------------------------------------------------------------------------------
/ext/logvs/vs.sh:
--------------------------------------------------------------------------------
1 | #/bin/sh
2 | rm -rf /tmp/*.txt
3 | rm -rf /tmp/*.log
4 | echo ======================================================================
5 | # for i in {1..5}; do /usr/bin/time -v ./logvs none $*; done
6 | # echo ----------------------------------------------------------------------
7 | # for i in {1..5}; do /usr/bin/time -v ./logvs spdlog $*; done
8 | # echo ----------------------------------------------------------------------
9 | for i in {1..5}; do /usr/bin/time -v ./logvs mal $*; done
10 | echo ----------------------------------------------------------------------
11 | for i in {1..5}; do /usr/bin/time -v ./logvs fon9a $*; done
12 | echo ----------------------------------------------------------------------
13 | for i in {1..5}; do /usr/bin/time -v ./logvs fon9lf $*; done
14 | echo ----------------------------------------------------------------------
15 | for i in {1..5}; do /usr/bin/time -v ./logvs fon9 $*; done
16 | echo ======================================================================
17 | #ls -l /tmp
18 | #tail /tmp/*txt /tmp/*log
19 | wc -l /tmp/*txt /tmp/*log
20 | rm -rf /tmp/*.txt
21 | rm -rf /tmp/*.log
22 |
--------------------------------------------------------------------------------
/ext/logvs/vsall.sh:
--------------------------------------------------------------------------------
1 | #/bin/sh
2 | rm -rf /tmp/*.txt
3 | rm -rf /tmp/*.log
4 | echo ======================================================================
5 | /usr/bin/time -v ./logvs fon9 $*
6 | echo ----------------------------------------------------------------------
7 | #/usr/bin/time -v ./logvs nanolog $*
8 | echo ----------------------------------------------------------------------
9 | /usr/bin/time -v ./logvs spdlog $*
10 | echo ----------------------------------------------------------------------
11 | /usr/bin/time -v ./logvs fon9fmt $*
12 | echo ----------------------------------------------------------------------
13 | /usr/bin/time -v ./logvs mal $*
14 | echo ----------------------------------------------------------------------
15 | #/usr/bin/time -v ./logvs fon9s $*
16 | echo ======================================================================
17 | ls -l /tmp
18 | tail /tmp/*txt /tmp/*log
19 | wc -l /tmp/*txt /tmp/*log
20 | rm -rf /tmp/*.txt
21 | rm -rf /tmp/*.log
22 |
--------------------------------------------------------------------------------
/ext/sigslot/benchmark_f9s.cpp:
--------------------------------------------------------------------------------
1 | #include "benchmark_f9s.hpp"
2 |
3 | const char* f9s::LibraryName = "* fon9 Subr";
4 | const char* f9s::Remark = "fon9::SortedVector";
5 |
6 | NOINLINE(void f9s::validate_assert(std::size_t N))
7 | {
8 | return Benchmark::validation_assert(N);
9 | }
10 | NOINLINE(double f9s::construction(std::size_t N))
11 | {
12 | return Benchmark::construction(N);
13 | }
14 | NOINLINE(double f9s::destruction(std::size_t N))
15 | {
16 | return Benchmark::destruction(N);
17 | }
18 | NOINLINE(double f9s::connection(std::size_t N))
19 | {
20 | return Benchmark::connection(N);
21 | }
22 | NOINLINE(double f9s::emission(std::size_t N))
23 | {
24 | return Benchmark::emission(N);
25 | }
26 | NOINLINE(double f9s::combined(std::size_t N))
27 | {
28 | return Benchmark::combined(N);
29 | }
30 | NOINLINE(double f9s::threaded(std::size_t N))
31 | {
32 | return Benchmark::threaded(N);
33 | }
34 |
--------------------------------------------------------------------------------
/ext/sigslot/benchmark_f9u.cpp:
--------------------------------------------------------------------------------
1 | #include "benchmark_f9u.hpp"
2 |
3 | const char* f9u::LibraryName = "fon9 Subr(unsafe)";
4 | const char* f9u::Remark = "fon9::SortedVector";
5 |
6 | NOINLINE(void f9u::validate_assert(std::size_t N))
7 | {
8 | return Benchmark::validation_assert(N);
9 | }
10 | NOINLINE(double f9u::construction(std::size_t N))
11 | {
12 | return Benchmark::construction(N);
13 | }
14 | NOINLINE(double f9u::destruction(std::size_t N))
15 | {
16 | return Benchmark::destruction(N);
17 | }
18 | NOINLINE(double f9u::connection(std::size_t N))
19 | {
20 | return Benchmark::connection(N);
21 | }
22 | NOINLINE(double f9u::emission(std::size_t N))
23 | {
24 | return Benchmark::emission(N);
25 | }
26 | NOINLINE(double f9u::combined(std::size_t N))
27 | {
28 | return Benchmark::combined(N);
29 | }
30 | NOINLINE(double f9u::threaded(std::size_t N))
31 | {
32 | return 0.0;
33 | }
34 |
--------------------------------------------------------------------------------
/ext/yas/run.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 | set -e
3 | set -x
4 | g++ -O3 -DNDEBUG -std=c++11 main.cpp -I ~/devel/external/yas/include -I ~/devel/fon9 -L ~/devel/output/fon9/release/fon9 -lfon9_s -lpthread
5 | ./a.out
6 |
7 |
--------------------------------------------------------------------------------
/f9extests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(f9extests_src
2 | SymbIn.cpp
3 | SymbDyTest.cpp
4 | ExgMktTester.cpp
5 | )
6 | add_library(f9extests_s STATIC ${f9extests_src})
7 | target_link_libraries(f9extests_s pthread fon9_s)
8 |
9 | add_library(f9extests SHARED ${f9extests_src})
10 | target_link_libraries(f9extests pthread fon9)
11 |
--------------------------------------------------------------------------------
/f9extests/Config.h:
--------------------------------------------------------------------------------
1 | /// \file f9extests/Config.h
2 | ///
3 | /// libfon9 C API 的一些基本設定.
4 | ///
5 | /// \author fonwinz@gmail.com
6 | #ifndef __f9extests_Config_h__
7 | #define __f9extests_Config_h__
8 | #include "fon9/sys/Config.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #if defined(f9extests_NODLL)
15 | #define f9extests_API
16 | #elif defined(f9extests_EXPORT)
17 | #define f9extests_API __declspec(dllexport)
18 | #elif defined(fon9_WINDOWS)
19 | #define f9extests_API __declspec(dllimport)
20 | #else//not defined: fon9_WINDOWS
21 | #define f9extests_API
22 | #endif
23 |
24 |
25 | #ifdef __cplusplus
26 | }//extern "C"
27 | #endif
28 | #endif//__f9extests_Config_h__
29 |
--------------------------------------------------------------------------------
/f9extests/README.md:
--------------------------------------------------------------------------------
1 | fon9 extests
2 | ============
3 |
4 | 其他測試項目.
5 | * SymbIn: 一個商品資料直接包含 SymbRef、SymbDeal、SymbBS, 不使用動態建立。
--------------------------------------------------------------------------------
/f9twf/Config.h:
--------------------------------------------------------------------------------
1 | // \file f9twf/Config.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_Config_h__
4 | #define __f9twf_Config_h__
5 | #include "fon9/sys/Config.h"
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #if defined(fon9_WINDOWS)
11 | /// C API 的呼叫方式, Windows: __stdcall
12 | #define f9twf_CAPI_CALL __stdcall
13 | #else//#if WIN #else...
14 | /// C API 的呼叫方式, Windows: __stdcall, unix: 空白(不須額外定義).
15 | #define f9twf_CAPI_CALL
16 | #endif//#if WIN #else #endif
17 |
18 | /// 設定 f9twf_API: MSVC 的 DLL import/export.
19 | #if defined(f9twf_NODLL)
20 | #define f9twf_API
21 | #elif defined(f9twf_EXPORT)
22 | #define f9twf_API __declspec(dllexport)
23 | #elif defined(f9twf_WINDOWS)
24 | #define f9twf_API __declspec(dllimport)
25 | #else//not defined: fon9_WINDOWS
26 | #define f9twf_API
27 | #endif
28 |
29 | #ifdef __cplusplus
30 | }//extern "C"
31 | #endif
32 | #endif//__f9twf_Config_h__
33 |
--------------------------------------------------------------------------------
/f9twf/ExgMapFcmId.cpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMapFcmId.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9twf/ExgMapFcmId.hpp"
4 | #include "fon9/StrTo.hpp"
5 |
6 | namespace f9twf {
7 |
8 | void ExgMapBrkFcmId::AddItem(ExgBrkFcmId id) {
9 | const_cast(&this->BrkToFcm_.kfetch(id.BrkId_))->FcmId_ = id.FcmId_;
10 | const_cast(&this->FcmToBrk_.kfetch(id.FcmId_))->BrkId_ = id.BrkId_;
11 | }
12 | void ExgMapBrkFcmId::AddItem(const TmpP06& p06) {
13 | ExgBrkFcmId id;
14 | id.BrkId_ = p06.BrkId_;
15 | id.FcmId_ = fon9::StrTo(ToStrView(p06.FcmId_), FcmId{});
16 | this->AddItem(id);
17 | }
18 | void ExgMapBrkFcmId::LoadP06(fon9::StrView fctx) {
19 | const TmpP06* p06 = reinterpret_cast(fctx.begin());
20 | while (reinterpret_cast(&p06[1]) > fctx.end())
21 | this->AddItem(*p06++);
22 | }
23 |
24 | } // namespaces
25 |
--------------------------------------------------------------------------------
/f9twf/ExgMapSessionDn.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMapSessionDn.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMapSessionDn_hpp__
4 | #define __f9twf_ExgMapSessionDn_hpp__
5 | #include "f9twf/ExgMapFcmId.hpp"
6 | #include "f9twf/ExgLineTmpArgs.hpp"
7 |
8 | namespace f9twf {
9 |
10 | /// 期交所 P07、PA7: SessionId => dn:port 對照表.
11 | class f9twf_API ExgMapSessionDn {
12 | using ExgSessionKey = uint32_t;
13 | static_assert(sizeof(ExgSessionKey) >= sizeof(FcmId) + sizeof(SessionId),
14 | "ExgSessionKey too small.");
15 | using SesToDn = fon9::SortedVector;
16 | SesToDn SesToDn_;
17 |
18 | public:
19 | void reserve(size_t sz) {
20 | this->SesToDn_.reserve(sz);
21 | }
22 | void shrink_to_fit() {
23 | this->SesToDn_.shrink_to_fit();
24 | }
25 | void swap(ExgMapSessionDn& rhs) {
26 | this->SesToDn_.swap(rhs.SesToDn_);
27 | }
28 |
29 | /// 載入期交所P07、PA7.
30 | void LoadP07(const ExgMapBrkFcmId& mapFcmId, fon9::StrView fctx);
31 |
32 | /// 設定一筆(一行) dn, 使用 P07 格式.
33 | bool FeedLine(const ExgMapBrkFcmId& mapFcmId, fon9::StrView ctxln);
34 |
35 | /// 在 devcfg 尾端加上 "|dn=...";
36 | bool AppendDn(const ExgLineTmpArgs& lineArgs, std::string& devcfg) const;
37 | };
38 |
39 | } // namespaces
40 | #endif//__f9twf_ExgMapSessionDn_hpp__
41 |
--------------------------------------------------------------------------------
/f9twf/ExgMcChannelTunnel.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMcChannelTunnel.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMcChannelTunnel_hpp__
4 | #define __f9twf_ExgMcChannelTunnel_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 | #include "fon9/framework/IoFactory.hpp"
7 |
8 | namespace f9twf {
9 |
10 | /// 台灣期交所逐筆行情「Channel訊息轉發程序」工廠.
11 | class f9twf_API ExgMcChannelTunnelFactory : public fon9::SessionFactory {
12 | fon9_NON_COPY_NON_MOVE(ExgMcChannelTunnelFactory);
13 | using base = fon9::SessionFactory;
14 | public:
15 | using base::base;
16 | fon9::io::SessionSP CreateSession(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
17 | fon9::io::SessionServerSP CreateSessionServer(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
18 | };
19 |
20 | } // namespaces
21 | #endif//__f9twf_ExgMcChannelTunnel_hpp__
22 |
--------------------------------------------------------------------------------
/f9twf/ExgMcFmtSSToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMcFmtSSToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMcFmtSSToRts_hpp__
4 | #define __f9twf_ExgMcFmtSSToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_);
10 | /// - 透過 symb.MdRtStream_ 發行 & 儲存.
11 | /// - 轉發 I083 給 RealtimeChannel;
12 | /// - 若沒有儲存, 則盤中重啟後, Rti 儲存的「BS明細」,
13 | /// 可能無法正確處理接續的 UpdateBS;
14 | f9twf_API void I084SSParserToRts(ExgMcMessage& e);
15 | f9twf_API void I084SSParserToRtsV3(ExgMcMessage& e);
16 |
17 | } // namespaces
18 | #endif//__f9twf_ExgMcFmtSSToRts_hpp__
19 |
--------------------------------------------------------------------------------
/f9twf/ExgMcReceiverFactory.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMcReceiverFactory.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMcReceiverFactory_hpp__
4 | #define __f9twf_ExgMcReceiverFactory_hpp__
5 | #include "f9twf/Config.h"
6 | #include "fon9/framework/IoFactory.hpp"
7 |
8 | namespace f9twf {
9 |
10 | class f9twf_API ExgMcReceiverFactory : public fon9::SessionFactory {
11 | fon9_NON_COPY_NON_MOVE(ExgMcReceiverFactory);
12 | using base = fon9::SessionFactory;
13 | public:
14 | using base::base;
15 |
16 | fon9::io::SessionSP CreateSession(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
17 | fon9::io::SessionServerSP CreateSessionServer(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
18 | };
19 |
20 | } // namespaces
21 | #endif//__f9twf_ExgMcReceiverFactory_hpp__
22 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtBSToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtBSToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtBSToRts_hpp__
4 | #define __f9twf_ExgMdFmtBSToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_);
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I081BSParserToRts(ExgMcMessage& e);
12 |
13 | /// 解析 static_cast(&e.Pk_);
14 | /// 並透過 symb.MdRtStream_ 發行.
15 | f9twf_API void I083BSParserToRts(ExgMcMessage& e);
16 |
17 | } // namespaces
18 | #endif//__f9twf_ExgMdFmtBSToRts_hpp__
19 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtBasicInfoToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtBasicInfoToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtBasicInfoToRts_hpp__
4 | #define __f9twf_ExgMdFmtBasicInfoToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_);
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I010BasicInfoParserToRts_V7(ExgMcMessage& e);
12 | f9twf_API void I010BasicInfoParserToRts_V8(ExgMcMessage& e);
13 |
14 | f9twf_API void I012BasePriLmts(ExgMcMessage& e);
15 |
16 | } // namespaces
17 | #endif//__f9twf_ExgMdFmtBasicInfoToRts_hpp__
18 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtClosingToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtClosingToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtClosingToRts_hpp__
4 | #define __f9twf_ExgMdFmtClosingToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_); 結算價.
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I071ClosingParserToRts(ExgMcMessage& e);
12 |
13 | /// 解析 static_cast(&e.Pk_); 結算價.
14 | /// 並透過 symb.MdRtStream_ 發行.
15 | f9twf_API void I072ClosingParserToRts(ExgMcMessage& e);
16 |
17 | } // namespaces
18 | #endif//__f9twf_ExgMdFmtClosingToRts_hpp__
19 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtHL.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtHL.hpp
2 | //
3 | // 台灣期交所行情格式: 盤中最(高)低價揭示.
4 | // 逐筆行情: I025;
5 | // 間隔行情: I021;
6 | //
7 | // \author fonwinz@gmail.com
8 | #ifndef __f9twf_ExgMdFmtHL_hpp__
9 | #define __f9twf_ExgMdFmtHL_hpp__
10 | #include "f9twf/ExgMdFmt.hpp"
11 |
12 | namespace f9twf {
13 | fon9_PACK(1);
14 |
15 | struct ExgMdDayHighLow {
16 | ExgMdSPrice DayHighPrice_;
17 | ExgMdSPrice DayLowPrice_;
18 | ExgMdHHMMSSu6 ShowTime_;
19 | };
20 | //--------------------------------------------------------------------------//
21 | /// 逐筆行情 盤中最(高)低價揭示: Fut:(Tx='2'; Mg='E'); Opt:(Tx='5'; Mg='E'); Ver=1;
22 | struct ExgMcI025Head : public ExgMcHead {
23 | ExgMdProdId20 ProdId_;
24 | ExgMcProdMsgSeq ProdMsgSeq_;
25 | };
26 | struct ExgMcI025 : public ExgMcI025Head
27 | , public ExgMdDayHighLow
28 | , public ExgMdTail {
29 | };
30 | //--------------------------------------------------------------------------//
31 | /// 間隔行情 盤中最(高)低價揭示: Fut:(Tx='2'; Mg='5'); Opt:(Tx='5'; Mg='5'); Ver=3;
32 | struct ExgMiI021Head : public ExgMiHead {
33 | ExgMdProdId20 ProdId_;
34 | };
35 | struct ExgMiI021 : public ExgMiI021Head
36 | , public ExgMdDayHighLow
37 | , public ExgMdTail {
38 | };
39 |
40 | fon9_PACK_POP;
41 | } // namespaces
42 | #endif//__f9twf_ExgMdFmtHL_hpp__
43 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtMatchToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtMatchToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtMatchToRts_hpp__
4 | #define __f9twf_ExgMdFmtMatchToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_);
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I024MatchParserToRts(ExgMcMessage& e);
12 |
13 | } // namespaces
14 | #endif//__f9twf_ExgMdFmtMatchToRts_hpp__
15 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtQuoteReq.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtQuoteReq.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtQuoteReq_hpp__
4 | #define __f9twf_ExgMdFmtQuoteReq_hpp__
5 | #include "f9twf/ExgMdFmt.hpp"
6 |
7 | namespace f9twf {
8 | fon9_PACK(1);
9 |
10 | struct ExgMdQuoteReq {
11 | ExgMdProdId10 ProdId_;
12 | ExgMdHHMMSSu6 DisclosureTime_;
13 | fon9::PackBcd<3> DurationSeconds_;
14 | };
15 | //--------------------------------------------------------------------------//
16 | /// 逐筆行情 詢價要求揭示: Fut:(Tx='2'; Mg='4'); Opt:(Tx='5'; Mg='4'); Ver=2;
17 | struct ExgMcI100 : public ExgMcHead
18 | , public ExgMdQuoteReq
19 | , public ExgMdTail {
20 | };
21 | //--------------------------------------------------------------------------//
22 | /// 間隔行情 詢價要求揭示: Fut:(Tx='2'; Mg='4'); Opt:(Tx='5'; Mg='4'); Ver=2;
23 | struct ExgMiI100 : public ExgMiHead
24 | , public ExgMdQuoteReq
25 | , public ExgMdTail {
26 | };
27 |
28 | fon9_PACK_POP;
29 | } // namespaces
30 | #endif//__f9twf_ExgMdFmtQuoteReq_hpp__
31 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtQuoteReqToRts.cpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtQuoteReqToRts.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9twf/ExgMdFmtQuoteReqToRts.hpp"
4 | #include "f9twf/ExgMdFmtQuoteReq.hpp"
5 | #include "f9twf/ExgMdFmtParsers.hpp"
6 | #include "fon9/fmkt/SymbTabNames.h"
7 |
8 | namespace f9twf {
9 | namespace f9fmkt = fon9::fmkt;
10 |
11 | f9twf_API void I100QuoteReqParserToRts(ExgMcMessage& e) {
12 | const auto& pk = *static_cast(&e.Pk_);
13 | f9fmkt::SymbQuoteReq_Data quoteReq;
14 | quoteReq.DisclosureTime_ = pk.DisclosureTime_.ToDayTime();
15 | quoteReq.DurationSeconds_ = fon9::PackBcdTo(pk.DurationSeconds_);
16 |
17 | ExgMdLocker lk{e, pk.ProdId_};
18 | auto& symb = *e.Symb_;
19 | if (symb.QuoteReq_.Data_ == quoteReq)
20 | return;
21 | symb.QuoteReq_.Data_ = quoteReq;
22 | fon9::RevBufferList rbuf{128};
23 | auto* tabQuoteReq = lk.Symbs_.LayoutSP_->GetTab(fon9_kCSTR_TabName_QuoteReq);
24 | f9fmkt::MdRtsPackTabValues(rbuf, *tabQuoteReq, symb.QuoteReq_);
25 | symb.MdRtStream_.Publish(ToStrView(symb.SymbId_),
26 | f9sv_RtsPackType_TabValues_AndInfoTime,
27 | f9sv_MdRtsKind_QuoteReq,
28 | e.Pk_.InformationTime_.ToDayTime(),
29 | std::move(rbuf));
30 | }
31 |
32 | } // namespaces
33 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtQuoteReqToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtQuoteReqToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtQuoteReqToRts_hpp__
4 | #define __f9twf_ExgMdFmtQuoteReqToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_); 詢價訊息.
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I100QuoteReqParserToRts(ExgMcMessage& e);
12 |
13 | } // namespaces
14 | #endif//__f9twf_ExgMdFmtQuoteReqToRts_hpp__
15 |
--------------------------------------------------------------------------------
/f9twf/ExgMdFmtSysInfoToRts.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdFmtSysInfoToRts.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdFmtSysInfoToRts_hpp__
4 | #define __f9twf_ExgMdFmtSysInfoToRts_hpp__
5 | #include "f9twf/ExgMcChannel.hpp"
6 |
7 | namespace f9twf {
8 |
9 | /// 解析 static_cast(&e.Pk_);
10 | /// 並透過 symb.MdRtStream_ 發行.
11 | f9twf_API void I140SysInfoParserToRts(ExgMcMessage& e);
12 |
13 | } // namespaces
14 | #endif//__f9twf_ExgMdFmtSysInfoToRts_hpp__
15 |
--------------------------------------------------------------------------------
/f9twf/ExgMdPkReceiver.cpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdPkReceiver.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9twf/ExgMdPkReceiver.hpp"
4 |
5 | namespace f9twf {
6 |
7 | ExgMiPkReceiver::~ExgMiPkReceiver() {
8 | }
9 | unsigned ExgMiPkReceiver::GetPkSize(const void* pkptr) {
10 | return GetPkSize_ExgMi(*reinterpret_cast(pkptr));
11 | }
12 |
13 | ExgMcPkReceiver::~ExgMcPkReceiver() {
14 | }
15 | unsigned ExgMcPkReceiver::GetPkSize(const void* pkptr) {
16 | return GetPkSize_ExgMc(*reinterpret_cast(pkptr));
17 | }
18 |
19 | } // namespaces
20 |
--------------------------------------------------------------------------------
/f9twf/ExgMdPkReceiver.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgMdPkReceiver.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_ExgMdPkReceiver_hpp__
4 | #define __f9twf_ExgMdPkReceiver_hpp__
5 | #include "f9twf/ExgMdFmt.hpp"
6 | #include "fon9/PkReceiver.hpp"
7 |
8 | namespace f9twf {
9 |
10 | /// 解析台灣期交所「間隔行情」格式框架.
11 | class f9twf_API ExgMiPkReceiver : public fon9::PkReceiver {
12 | fon9_NON_COPY_NON_MOVE(ExgMiPkReceiver);
13 | using base = fon9::PkReceiver;
14 | public:
15 | ExgMiPkReceiver(bool isDgram = false)
16 | : base{sizeof(ExgMiHead), isDgram} {
17 | }
18 | virtual ~ExgMiPkReceiver();
19 |
20 | unsigned GetPkSize(const void* pkptr) override;
21 | };
22 |
23 | /// 解析台灣期交所「逐筆行情」格式框架.
24 | class f9twf_API ExgMcPkReceiver : public fon9::PkReceiver {
25 | fon9_NON_COPY_NON_MOVE(ExgMcPkReceiver);
26 | using base = fon9::PkReceiver;
27 | public:
28 | ExgMcPkReceiver (bool isDgram = false)
29 | : base{sizeof(ExgMcHead), isDgram} {
30 | }
31 | virtual ~ExgMcPkReceiver();
32 |
33 | unsigned GetPkSize(const void* pkptr) override;
34 | };
35 |
36 | } // namespaces
37 | #endif//__f9twf_ExgMdPkReceiver_hpp__
38 |
--------------------------------------------------------------------------------
/f9twf/ExgTmpTradingR9.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgTmpTradingR9.hpp
2 | //
3 | // TMP封包: 報價要求R09/R39; 報價回報使用: (R02/R32) * 2(Bid/Offer).
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __f9twf_ExgTmpTradingR9_hpp__
7 | #define __f9twf_ExgTmpTradingR9_hpp__
8 | #include "f9twf/ExgTmpTradingR1.hpp"
9 |
10 | namespace f9twf {
11 |
12 | struct TmpR9Front : public TmpHeader, public TmpR1BfSym {
13 | struct BackType {
14 | TmpPrice BidPx_;
15 | TmpPrice OfferPx_;
16 | TmpQty BidSize_;
17 | TmpQty OfferSize_;
18 | TmpIvacNo IvacNo_;
19 | TmpIvacFlag IvacFlag_;
20 | TmpTimeInForce TimeInForce_;
21 | TmpPosEff PosEff_;
22 | TmpSource Source_;
23 | TmpCheckSum CheckSum_;
24 | };
25 | };
26 | using TmpR9Back = TmpR9Front::BackType;
27 | using TmpR09 = TmpTriDef;
28 | using TmpR39 = TmpTriDef;
29 |
30 | static_assert(sizeof(TmpR09) == 84, "struct TmpR09; must pack?");
31 | static_assert(sizeof(TmpR39) == 104, "struct TmpR39; must pack?");
32 |
33 | } // namespaces
34 | #endif//__f9twf_ExgTmpTradingR9_hpp__
35 |
--------------------------------------------------------------------------------
/f9twf/ExgTradingLineMgr.cpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/ExgTradingLineMgr.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9twf/ExgTradingLineMgr.hpp"
4 |
5 | namespace f9twf {
6 |
7 | void ExgTradingLineMgr::OnParentSeedClear() {
8 | this->OnBeforeDestroy();
9 | baseIo::OnParentSeedClear();
10 | }
11 | void ExgTradingLineMgr::OnTDayChanged(fon9::TimeStamp tday, std::string cause) {
12 | (void)tday;
13 | this->DisposeAndReopen(std::move(cause));
14 | }
15 |
16 | } // namespaces
17 |
--------------------------------------------------------------------------------
/f9twf/TwfTickSize.hpp:
--------------------------------------------------------------------------------
1 | // \file f9twf/TwfTickSize.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9twf_TwfTickSize_hpp__
4 | #define __f9twf_TwfTickSize_hpp__
5 | #include "fon9/fmkt/FmktTools.hpp"
6 | #include "f9twf/ExgTypes.hpp"
7 | #include "f9twf/Config.h"
8 |
9 | namespace f9twf {
10 |
11 | /// 使用 ConfigLoader 載入 TickSize 設定.
12 | f9twf_API void Load_TwfTickSize(fon9::StrView defaultConfigPath = "", fon9::StrView cfgFileName = fon9::StrView("TwfTickSize.cfg"));
13 |
14 | f9twf_API const fon9::fmkt::LvPriStep* GetLvPriStep(ContractId contractId, f9fmkt_TradingMarket mkt, ExgContractType contractType);
15 |
16 | } // namespaces
17 | #endif//__f9twf_TwfTickSize_hpp__
18 |
--------------------------------------------------------------------------------
/f9tws/Config.h:
--------------------------------------------------------------------------------
1 | // \file f9tws/Config.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_Config_h__
4 | #define __f9tws_Config_h__
5 | #include "fon9/sys/Config.h"
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #if defined(fon9_WINDOWS)
11 | /// C API 的呼叫方式, Windows: __stdcall
12 | #define f9tws_CAPI_CALL __stdcall
13 | #else//#if WIN #else...
14 | /// C API 的呼叫方式, Windows: __stdcall, unix: 空白(不須額外定義).
15 | #define f9tws_CAPI_CALL
16 | #endif//#if WIN #else #endif
17 |
18 | /// 設定 f9tws_API: MSVC 的 DLL import/export.
19 | #if defined(f9tws_NODLL)
20 | #define f9tws_API
21 | #elif defined(f9tws_EXPORT)
22 | #define f9tws_API __declspec(dllexport)
23 | #elif defined(f9tws_WINDOWS)
24 | #define f9tws_API __declspec(dllimport)
25 | #else//not defined: fon9_WINDOWS
26 | #define f9tws_API
27 | #endif
28 |
29 | #ifdef __cplusplus
30 | }//extern "C"
31 | #endif
32 | #endif//__f9tws_Config_h__
33 |
--------------------------------------------------------------------------------
/f9tws/ExgLineArgs.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgLineArgs.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgLineArgs_hpp__
4 | #define __f9tws_ExgLineArgs_hpp__
5 | #include "f9tws/ExgTypes.hpp"
6 | #include "fon9/fmkt/FmktTypes.hpp"
7 | #include "fon9/CharAry.hpp"
8 | #include "fon9/ConfigParser.hpp"
9 |
10 | namespace f9tws {
11 |
12 | struct f9tws_API ExgLineArgs {
13 | f9fmkt_TradingMarket Market_;
14 | BrkId BrkId_;
15 | fon9::CharAryF<2> SocketId_;
16 | fon9::CharAry<15> PassKey_;
17 | uint16_t PassNum_;
18 | /// Hb 的間隔(單位:秒), 預設為 0, 由各 session 根據交易所規範, 自行決定預設值.
19 | uint16_t HbInterval_;
20 |
21 | void Clear();
22 |
23 | /// 不改變 args.Market_ 您必須自行處理.
24 | /// - tag = "BrkId=|SocketId=|Pass=|HbInt=";
25 | /// - tag = "SocketId" 與 "PvcId" 相同, 都會填入 SocketId_;
26 | /// - tag = "PassKey" 則必須自定 FnGetPassNum;
27 | fon9::ConfigParser::Result OnTagValue(fon9::StrView tag, fon9::StrView& value);
28 |
29 | /// 檢查欄位是否正確.
30 | std::string Verify() const;
31 |
32 | uint16_t GetPassNum() const;
33 | };
34 |
35 | } // namespaces
36 | #endif//__f9tws_ExgLineArgs_hpp__
37 |
--------------------------------------------------------------------------------
/f9tws/ExgLineFactory.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgLineFactory.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgLineFactory.hpp"
4 |
5 | namespace f9tws {
6 |
7 | ExgLineFactory::ExgLineFactory(std::string logPathFmt, Named&& name)
8 | : baseFactory{std::move(name)}
9 | , basePathMaker{std::move(logPathFmt)} {
10 | }
11 | fon9::io::SessionServerSP ExgLineFactory::CreateSessionServer(fon9::IoManager& mgr, const fon9::IoConfigItem& cfg, std::string& errReason) {
12 | (void)mgr; (void)cfg;
13 | errReason = "f9tws::ExgLineFactory|err=Not support Server.";
14 | return fon9::io::SessionServerSP{};
15 | }
16 | fon9::io::SessionSP ExgLineFactory::CreateSession(fon9::IoManager& mgr, const fon9::IoConfigItem& cfg, std::string& errReason) {
17 | if (ExgTradingLineMgr* twsLineMgr = dynamic_cast(&mgr))
18 | return this->CreateTradingLine(*twsLineMgr, cfg, errReason);
19 | errReason = "IoManager must be f9tws::ExgTradingLineMgr";
20 | return fon9::io::SessionSP{};
21 | }
22 |
23 | } // namespaces
24 |
--------------------------------------------------------------------------------
/f9tws/ExgLineFactory.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgLineFactory.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgLineFactory_hpp__
4 | #define __f9tws_ExgLineFactory_hpp__
5 | #include "f9tws/ExgTradingLineMgr.hpp"
6 | #include "fon9/framework/IoFactory.hpp"
7 |
8 | namespace f9tws {
9 |
10 | class f9tws_API ExgLineFactory : public fon9::SessionFactory, public f9fmkt::TradingLineLogPathMaker {
11 | fon9_NON_COPY_NON_MOVE(ExgLineFactory);
12 | using baseFactory = fon9::SessionFactory;
13 | using basePathMaker = f9fmkt::TradingLineLogPathMaker;
14 |
15 | protected:
16 | virtual fon9::io::SessionSP CreateTradingLine(ExgTradingLineMgr& lineMgr,
17 | const fon9::IoConfigItem& cfg,
18 | std::string& errReason) = 0;
19 |
20 | public:
21 | ExgLineFactory(std::string logPathFmt, Named&& name);
22 |
23 | /// mgr 必須是 f9tws::ExgTradingLineMgr
24 | fon9::io::SessionSP CreateSession(fon9::IoManager& mgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
25 | /// 券商端, 不支援 SessionServer.
26 | fon9::io::SessionServerSP CreateSessionServer(fon9::IoManager& mgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
27 | };
28 |
29 | } // namespaces
30 | #endif//__f9tws_ExgLineFactory_hpp__
31 |
--------------------------------------------------------------------------------
/f9tws/ExgLineTmpFactory.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgLineTmpFactory.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgLineTmpFactory_hpp__
4 | #define __f9tws_ExgLineTmpFactory_hpp__
5 | #include "f9tws/ExgLineFactory.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgLineTmpArgs;
10 |
11 | class f9tws_API ExgLineTmpFactory : public ExgLineFactory {
12 | fon9_NON_COPY_NON_MOVE(ExgLineTmpFactory);
13 | using base = ExgLineFactory;
14 | protected:
15 | fon9::io::SessionSP CreateTradingLine(ExgTradingLineMgr& lineMgr,
16 | const fon9::IoConfigItem& cfg,
17 | std::string& errReason) override;
18 |
19 | /// 由衍生者根據 args.ApCode_ 決定要建立哪種 Session.
20 | virtual fon9::io::SessionSP CreateLineTmp(ExgTradingLineMgr& lineMgr,
21 | const ExgLineTmpArgs& args,
22 | std::string& errReason,
23 | std::string logFileName) = 0;
24 | public:
25 | ExgLineTmpFactory(std::string logPathFmt, Named&& name);
26 | };
27 |
28 | } // namespaces
29 | #endif//__f9tws_ExgLineTmpFactory_hpp__
30 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt13.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt13.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt13_hpp__
4 | #define __f9tws_ExgMdFmt13_hpp__
5 | #include "f9tws/ExgMdFmt.hpp"
6 |
7 | namespace f9tws {
8 | fon9_PACK(1);
9 |
10 | struct ExgMdFmt13v3 : public ExgMdHead {
11 | StkNo StkNo_;
12 | /// a.數值 < 143000 表示為試算揭示.
13 | /// b.數值 = 143000 表示為正式撮合成交揭示.
14 | /// c.數值 = 999999,StkNo_ = "000000" 表示當日零股交易撮合成交資料已全部送出。
15 | ExgMdHHMMSS Time_;
16 | bool IsLastDealSent() const {
17 | return this->Time_.HH_[0] == 0x99;
18 | }
19 |
20 | /// Bit 7-6 成交 00:一般成交或無成交 01:跌停成交 10:漲停成交.
21 | /// Bit 5-4 買進 00:一般買進或無買進價量 01:跌停買進 10:漲停買進.
22 | /// Bit 3-2 賣出 00:一般賣出或無賣出價量 01:跌停賣出 10:漲停賣出.
23 | /// Bit 1-0 保留位元.
24 | fon9::byte LmtMask_;
25 |
26 | fon9::PackBcd<9> TradingPriceV4_;
27 | /// 成交股數,單位為「股」.
28 | fon9::PackBcd<12> TradingVolume_;
29 | /// 揭示試算及正式撮合後未成交的最佳一檔買進價格,沒有未成交買進價格時傳送 0。
30 | fon9::PackBcd<9> BuyPriceV4_;
31 | /// 揭示試算及正式撮合後未成交的最佳一檔賣出價格,沒有未成交賣出價格時傳送 0。
32 | fon9::PackBcd<9> SellPriceV4_;
33 | };
34 | fon9_PACK_POP;
35 |
36 | } // namespaces
37 | #endif//__f9tws_ExgMdFmt13_hpp__
38 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt13Handler.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt13Handler.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt13Handler_hpp__
4 | #define __f9tws_ExgMdFmt13Handler_hpp__
5 | #include "f9tws/ExgMdSystem.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgMdFmt13Handler : public ExgMdHandlerPkCont {
10 | fon9_NON_COPY_NON_MOVE(ExgMdFmt13Handler);
11 | void PkContOnReceived(const void* pk, unsigned pksz, SeqT seq) override;
12 | public:
13 | using ExgMdHandlerPkCont::ExgMdHandlerPkCont;
14 | virtual ~ExgMdFmt13Handler();
15 | };
16 |
17 | } // namespaces
18 | #endif//__f9tws_ExgMdFmt13Handler_hpp__
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt19.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt19.hpp
2 | //
3 | // 格式19: 當日暫停/恢復交易股票資料.
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __f9tws_ExgMdFmt19_hpp__
7 | #define __f9tws_ExgMdFmt19_hpp__
8 | #include "f9tws/ExgMdFmt.hpp"
9 |
10 | namespace f9tws {
11 | fon9_PACK(1);
12 |
13 | struct ExgMdFmt19 : public ExgMdHead {
14 | StkNo StkNo_;
15 | /// 當日暫停交易時間.
16 | fon9::PackBcd<6> SuspendHHMMSS_;
17 | /// 當日恢復交易時間 .
18 | fon9::PackBcd<6> ResumeHHMMSS_;
19 | };
20 |
21 | fon9_PACK_POP;
22 | } // namespaces
23 | #endif//__f9tws_ExgMdFmt19_hpp__
24 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt19Handler.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt19Handler.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt19Handler_hpp__
4 | #define __f9tws_ExgMdFmt19Handler_hpp__
5 | #include "f9tws/ExgMdSystem.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgMdFmt19Handler : public ExgMdHandlerAnySeq {
10 | fon9_NON_COPY_NON_MOVE(ExgMdFmt19Handler);
11 | void OnPkReceived(const ExgMdHead& pk, unsigned pksz) override;
12 | public:
13 | using ExgMdHandlerAnySeq::ExgMdHandlerAnySeq;
14 | virtual ~ExgMdFmt19Handler();
15 | };
16 |
17 | } // namespaces
18 | #endif//__f9tws_ExgMdFmt19Handler_hpp__
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt22Handler.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt22Handler.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgMdFmt22Handler.hpp"
4 | #include "f9tws/ExgMdFmt1Handler.hpp"
5 | #include "f9tws/ExgMdFmt22.hpp"
6 |
7 | namespace f9tws {
8 |
9 | ExgMdFmt22Handler::~ExgMdFmt22Handler() {
10 | }
11 | void ExgMdFmt22Handler::OnPkReceived(const ExgMdHead& pkhdr, unsigned pksz) {
12 | const ExgMdFmt22v1& fmt22 = *static_cast(&pkhdr);
13 | EdgMdParseBaseInfo(fon9::PackBcdTo(pkhdr.Market_) == ExgMdMarket_TwTSE
14 | ? f9fmkt_TradingMarket_TwSEC : f9fmkt_TradingMarket_TwOTC,
15 | *this, *TwsMdSys(*this).SymbsOdd_,
16 | fmt22, pksz);
17 | }
18 |
19 | } // namespaces
20 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt22Handler.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt22Handler.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt22Handler_hpp__
4 | #define __f9tws_ExgMdFmt22Handler_hpp__
5 | #include "f9tws/ExgMdSystem.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgMdFmt22Handler : public ExgMdHandlerAnySeq {
10 | fon9_NON_COPY_NON_MOVE(ExgMdFmt22Handler);
11 | void OnPkReceived(const ExgMdHead& pk, unsigned pksz) override;
12 | public:
13 | using ExgMdHandlerAnySeq::ExgMdHandlerAnySeq;
14 | virtual ~ExgMdFmt22Handler();
15 | };
16 |
17 | } // namespaces
18 | #endif//__f9tws_ExgMdFmt22Handler_hpp__
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt23.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt23.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt23_hpp__
4 | #define __f9tws_ExgMdFmt23_hpp__
5 | #include "f9tws/ExgMdFmt6.hpp"
6 |
7 | namespace f9tws {
8 | fon9_PACK(1);
9 |
10 | using ExgMdOddQty = fon9::PackBcd<12>;
11 | struct ExgMdOddPriQty {
12 | fon9::PackBcd<9> PriV4_;
13 | ExgMdOddQty Qty_;
14 |
15 | void AssignTo(fon9::fmkt::PriQty& dst) const {
16 | dst.Pri_.Assign<4>(fon9::PackBcdTo(this->PriV4_));
17 | dst.Qty_ = fon9::PackBcdTo(this->Qty_);
18 | }
19 | };
20 |
21 | struct ExgMdFmt23v1 : public ExgMdFmtRtBase {
22 | ExgMdOddQty TotalQty_;
23 | ExgMdOddPriQty PQs_[1];
24 |
25 | bool HasBS() const {
26 | // 盤中零股採用集合競價,每次的 Fmt23 揭示都包含「買賣報價」,
27 | // 如果市場上確實沒有買賣,則 (this->ItemMask_ & 0x7e) 為 0;
28 | // 所以 Fmt23 的 HasBS() 總是為 true; 表示有提供買賣報價(有可能檔數為 0);
29 | // return (this->ItemMask_ & 0x7e) != 0;
30 | return true;
31 |
32 | // 格式6,採用逐筆撮合,有額外的旗標,用來標示該次 Fmt6 是否包含買賣報價。
33 | // return (this->ItemMask_ & 0x7e) || (this->ItemMask_ & 1) == 0;
34 | }
35 | };
36 | fon9_PACK_POP;
37 |
38 | } // namespaces
39 | #endif//__f9tws_ExgMdFmt23_hpp__
40 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt23Handler.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt23Handler.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgMdFmt23Handler.hpp"
4 | #include "f9tws/ExgMdFmt6Handler.hpp"
5 | #include "f9tws/ExgMdFmt23.hpp"
6 |
7 | namespace f9tws {
8 |
9 | ExgMdFmt23Handler::~ExgMdFmt23Handler() {
10 | }
11 | //--------------------------------------------------------------------------//
12 | void ExgMdFmt23Handler::PkContOnReceived(const void* pkptr, unsigned pksz, SeqT seq) {
13 | FmtRt_PkContOnReceived(
14 | *this, *TwsMdSys(*this).SymbsOdd_,
15 | *static_cast(pkptr), pksz, seq);
16 | }
17 |
18 | } // namespaces
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt23Handler.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt23Handler.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt23Handler_hpp__
4 | #define __f9tws_ExgMdFmt23Handler_hpp__
5 | #include "f9tws/ExgMdSystem.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgMdFmt23Handler : public ExgMdHandlerPkCont {
10 | fon9_NON_COPY_NON_MOVE(ExgMdFmt23Handler);
11 | void PkContOnReceived(const void* pk, unsigned pksz, SeqT seq) override;
12 | public:
13 | using ExgMdHandlerPkCont::ExgMdHandlerPkCont;
14 | virtual ~ExgMdFmt23Handler();
15 | };
16 |
17 | } // namespaces
18 | #endif//__f9tws_ExgMdFmt23Handler_hpp__
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt9.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt9.hpp
2 | //
3 | // 定價交易個股成交資料.
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __f9tws_ExgMdFmt9_hpp__
7 | #define __f9tws_ExgMdFmt9_hpp__
8 | #include "f9tws/ExgMdFmt.hpp"
9 |
10 | namespace f9tws {
11 | fon9_PACK(1);
12 |
13 | struct ExgMdFmt9 : public ExgMdHead {
14 | StkNo StkNo_;
15 | fon9::PackBcd<6> DealHHMMSS_;
16 | ExgMdPriQty DealPQ_;
17 | };
18 |
19 | fon9_PACK_POP;
20 | } // namespaces
21 | #endif//__f9tws_ExgMdFmt9_hpp__
22 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmt9Handler.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmt9Handler.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmt9Handler_hpp__
4 | #define __f9tws_ExgMdFmt9Handler_hpp__
5 | #include "f9tws/ExgMdSystem.hpp"
6 |
7 | namespace f9tws {
8 |
9 | class f9tws_API ExgMdFmt9Handler : public ExgMdHandlerAnySeq {
10 | fon9_NON_COPY_NON_MOVE(ExgMdFmt9Handler);
11 | void OnPkReceived(const ExgMdHead& pk, unsigned pksz) override;
12 | public:
13 | using ExgMdHandlerAnySeq::ExgMdHandlerAnySeq;
14 | virtual ~ExgMdFmt9Handler();
15 | };
16 |
17 | } // namespaces
18 | #endif//__f9tws_ExgMdFmt9Handler_hpp__
19 |
--------------------------------------------------------------------------------
/f9tws/ExgMdFmtIxNoList.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdFmtIxNoList.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdFmtIxNoList_hpp__
4 | #define __f9tws_ExgMdFmtIxNoList_hpp__
5 | #include "f9tws/ExgMdFmtIx.hpp"
6 |
7 | namespace f9tws {
8 |
9 | extern f9tws_API const IdxNo TwseIxNoList_[43];
10 | extern f9tws_API const IdxNo TpexIxNoList_[28];
11 |
12 | } // namespaces
13 | #endif//__f9tws_ExgMdFmtIxNoList_hpp__
14 |
--------------------------------------------------------------------------------
/f9tws/ExgMdPkReceiver.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdPkReceiver.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgMdPkReceiver.hpp"
4 |
5 | namespace f9tws {
6 |
7 | ExgMdPkReceiver::~ExgMdPkReceiver() {
8 | }
9 | unsigned ExgMdPkReceiver::GetPkSize(const void* pkptr) {
10 | return reinterpret_cast(pkptr)->GetLength();
11 | }
12 |
13 | } // namespaces
14 |
--------------------------------------------------------------------------------
/f9tws/ExgMdPkReceiver.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdPkReceiver.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdPkReceiver_hpp__
4 | #define __f9tws_ExgMdPkReceiver_hpp__
5 | #include "f9tws/ExgMdFmt.hpp"
6 | #include "fon9/PkReceiver.hpp"
7 |
8 | namespace f9tws {
9 |
10 | /// 解析台灣證券交易所(及櫃買中心)行情格式框架.
11 | class f9tws_API ExgMdPkReceiver : public fon9::PkReceiver {
12 | fon9_NON_COPY_NON_MOVE(ExgMdPkReceiver);
13 | using base = fon9::PkReceiver;
14 | public:
15 | ExgMdPkReceiver(bool isDgram = false)
16 | : base{sizeof(ExgMdHead), isDgram} {
17 | }
18 | virtual ~ExgMdPkReceiver();
19 |
20 | unsigned GetPkSize(const void* pkptr) override;
21 | };
22 |
23 | } // namespaces
24 | #endif//__f9tws_ExgMdPkReceiver_hpp__
25 |
--------------------------------------------------------------------------------
/f9tws/ExgMdReceiverFactory.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdReceiverFactory.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgMdReceiverFactory.hpp"
4 | #include "f9tws/ExgMdReceiverSession.hpp"
5 |
6 | namespace f9tws {
7 | using namespace fon9;
8 |
9 | io::SessionSP ExgMdReceiverFactory::CreateSession(IoManager& ioMgr, const IoConfigItem& cfg, std::string& errReason) {
10 | (void)ioMgr;
11 | StrView tag, value, args = ToStrView(cfg.SessionArgs_);
12 | StrView pkLogName;
13 | while (fon9::StrFetchTagValue(args, tag, value)) {
14 | if (tag == "PkLog")
15 | pkLogName = value;
16 | else {
17 | errReason = "f9tws.ExgMdReceiverFactory.CreateSession: Unknown Tag:" + tag.ToString();
18 | return nullptr;
19 | }
20 | }
21 | return new ExgMdReceiverSession(this->MdDispatcher_, pkLogName);
22 | }
23 | io::SessionServerSP ExgMdReceiverFactory::CreateSessionServer(IoManager& ioMgr, const IoConfigItem& cfg, std::string& errReason) {
24 | (void)ioMgr; (void)cfg;
25 | errReason = "f9tws.ExgMdReceiverFactory: Not support server.";
26 | return nullptr;
27 | }
28 |
29 | } // namespaces
30 |
--------------------------------------------------------------------------------
/f9tws/ExgMdReceiverFactory.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdReceiverFactory.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_ExgMdReceiverFactory_hpp__
4 | #define __f9tws_ExgMdReceiverFactory_hpp__
5 | #include "f9tws/ExgMdSystemBase.hpp"
6 | #include "fon9/framework/IoFactory.hpp"
7 |
8 | namespace f9tws {
9 |
10 | class f9tws_API ExgMdReceiverFactory : public fon9::SessionFactory {
11 | fon9_NON_COPY_NON_MOVE(ExgMdReceiverFactory);
12 | using base = fon9::SessionFactory;
13 | public:
14 | const ExgMdSystemBaseSP MdDispatcher_;
15 |
16 | template
17 | ExgMdReceiverFactory(ExgMdSystemBaseSP mdDispatcher, ArgsT&&... args)
18 | : base(std::forward(args)...)
19 | , MdDispatcher_(std::move(mdDispatcher)) {
20 | }
21 |
22 | fon9::io::SessionSP CreateSession(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
23 | fon9::io::SessionServerSP CreateSessionServer(fon9::IoManager& ioMgr, const fon9::IoConfigItem& cfg, std::string& errReason) override;
24 | };
25 |
26 | } // namespaces
27 | #endif//__f9tws_ExgMdReceiverFactory_hpp__
28 |
--------------------------------------------------------------------------------
/f9tws/ExgMdSystemBase.cpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/ExgMdSystemBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "f9tws/ExgMdSystemBase.hpp"
4 |
5 | namespace f9tws {
6 |
7 | ExgMdHandlerPkCont::~ExgMdHandlerPkCont() {
8 | }
9 | void ExgMdHandlerPkCont::OnLogSeqGap(fon9::PkContFeeder& rthis, fon9::RevBuffer& rbuf, const void* pk) {
10 | (void)rthis;
11 | fon9::RevPrint(rbuf, "TwsExgMd.Gap"
12 | "|mkt=", static_cast(pk)->GetMarket(),
13 | "|fmt=", static_cast(pk)->GetFmtNo());
14 | }
15 | //--------------------------------------------------------------------------//
16 | ExgMdSystemBase::~ExgMdSystemBase() {
17 | }
18 | void ExgMdSystemBase::OnMdSystemStartup(const unsigned tdayYYYYMMDD, const std::string& logPath) {
19 | base::OnMdSystemStartup(tdayYYYYMMDD, logPath);
20 | for (const ExgMdHandlerSP& pph : this->MdHandlers_) {
21 | if (pph.get())
22 | pph->DailyClear();
23 | }
24 | }
25 |
26 | } // namespaces
27 |
--------------------------------------------------------------------------------
/f9tws/TwsTools.hpp:
--------------------------------------------------------------------------------
1 | // \file f9tws/TwsTools.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __f9tws_TwsTools_hpp__
4 | #define __f9tws_TwsTools_hpp__
5 | #include "f9tws/TwsTypes.h"
6 | #include "f9tws/ExgTypes.hpp"
7 | #include "fon9/fmkt/FmktTools.hpp"
8 |
9 | inline f9tws_SymbKind StrTo(fon9::StrView s, f9tws_SymbKind null, const char** endptr = nullptr) {
10 | return static_cast(fon9::HexStrTo(s, endptr, null));
11 | }
12 | inline char* ToStrRev(char* pout, f9tws_SymbKind v) {
13 | return fon9::HexToStrRev(pout, fon9::cast_to_underlying(v));
14 | }
15 | //--------------------------------------------------------------------------//
16 | namespace f9tws {
17 |
18 | struct f9tws_API TwsSymbKindLvPriStep {
19 | f9tws_SymbKind Kind_;
20 | char Padding____[7];
21 | const fon9::fmkt::LvPriStep* LvPriSteps_;
22 |
23 | TwsSymbKindLvPriStep() = default;
24 | TwsSymbKindLvPriStep(StkNo stkno) {
25 | this->Setup(stkno);
26 | }
27 | void Setup(StkNo stkno);
28 | };
29 |
30 | } // namespaces
31 | #endif//__f9tws_TwsTools_hpp__
32 |
--------------------------------------------------------------------------------
/fon9/Assert.c:
--------------------------------------------------------------------------------
1 | /// \file fon9/Assert.c
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/Assert.h"
4 |
5 | #ifdef __cplusplus
6 | extern "C" {
7 | #endif
8 |
9 | #if defined(fon9_WINDOWS) && !defined(NDEBUG)
10 | fon9_API void fon9_wassert(
11 | _In_z_ wchar_t const* _Message,
12 | _In_z_ wchar_t const* _File,
13 | _In_ unsigned _Line
14 | ) {
15 | _wassert(_Message, _File, _Line);
16 | }
17 | #endif
18 |
19 | #ifdef __cplusplus
20 | }// extern "C"
21 | #endif
22 |
--------------------------------------------------------------------------------
/fon9/Assert.h:
--------------------------------------------------------------------------------
1 | /// \file fon9/Assert.h
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_Assert_h__
4 | #define __fon9_Assert_h__
5 | #include "fon9/sys/Config.h"
6 | #include
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | #if defined(fon9_WINDOWS) && !defined(NDEBUG)
13 | #undef assert
14 | #define assert(expression) (void)( \
15 | (!!(expression)) || \
16 | (fon9_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
17 | )
18 |
19 | // 為了 debug 時, 可以在這裡可以設定中斷, 所以改寫了 assert().
20 | fon9_API void fon9_wassert(
21 | _In_z_ wchar_t const* _Message,
22 | _In_z_ wchar_t const* _File,
23 | _In_ unsigned _Line
24 | );
25 | #endif
26 |
27 | #ifdef __cplusplus
28 | }// extern "C"
29 | #endif
30 | #endif//__fon9_Assert_h__
31 |
--------------------------------------------------------------------------------
/fon9/Base64_UT.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/Base64_UT.cpp
2 | // \author fonwinz@gmail.com
3 | #define _CRT_SECURE_NO_WARNINGS
4 | #include "fon9/Base64.hpp"
5 | #include "fon9/TestTools.hpp"
6 |
7 | //--------------------------------------------------------------------------//
8 |
9 | void TestB64(const std::string orig, const std::string b64) {
10 | char dst[1024];
11 | auto res = fon9::Base64Encode(dst, sizeof(dst), orig.c_str(), orig.size());
12 | fon9_CheckTestResult(("Base64Encode:" + orig).c_str(), b64 == std::string(dst, res.GetResult()));
13 | res = fon9::Base64Decode(dst, sizeof(dst), b64.c_str(), b64.size());
14 | fon9_CheckTestResult(("Base64Decode:" + b64).c_str(), orig == std::string(dst, res.GetResult()));
15 | }
16 |
17 | void TestAllB64() {
18 | TestB64("", "");
19 | TestB64("f", "Zg==");
20 | TestB64("fo", "Zm8=");
21 | TestB64("foo", "Zm9v");
22 | TestB64("foob", "Zm9vYg==");
23 | TestB64("fooba", "Zm9vYmE=");
24 | TestB64("foobar", "Zm9vYmFy");
25 | }
26 |
27 | //--------------------------------------------------------------------------//
28 |
29 | int main(int argc, char** args) {
30 | (void)argc; (void)args;
31 | #if defined(_MSC_VER) && defined(_DEBUG)
32 | _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
33 | //_CrtSetBreakAlloc(176);
34 | #endif
35 | fon9::AutoPrintTestInfo utinfo{"Base64"};
36 |
37 | TestAllB64();
38 | }
39 |
--------------------------------------------------------------------------------
/fon9/CStrView.h:
--------------------------------------------------------------------------------
1 | // \file fon9/CStrView.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_CStrView_h__
4 | #define __fon9_CStrView_h__
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif//__cplusplus
9 |
10 | /// 使用時, 除非有特別的說明,
11 | /// Begin_ 可以視為一般的 c 字串, *(End_) 為 '\0';
12 | struct fon9_CStrView_t {
13 | const char* Begin_;
14 | const char* End_;
15 | };
16 | typedef struct fon9_CStrView_t fon9_CStrView;
17 |
18 | #ifdef __cplusplus
19 | }//extern "C"
20 |
21 | template
22 | inline auto fon9_CStrViewFrom(fon9_CStrView& dst, const StrT& str)
23 | -> decltype(str.c_str(), void()) {
24 | dst.Begin_ = str.c_str();
25 | dst.End_ = dst.Begin_ + str.size();
26 | }
27 |
28 | template
29 | inline auto fon9_ToCStrView(const StrT& str) -> decltype(fon9_CStrView{str.c_str(),str.c_str()+str.size()}) {
30 | fon9_CStrView retval;
31 | fon9_CStrViewFrom(retval, str);
32 | return retval;
33 | }
34 | template
35 | inline auto fon9_ToCStrView(const StrT& str) -> decltype(fon9_CStrView(ToStrView(str).ToCStrView())) {
36 | return ToStrView(str).ToCStrView();
37 | }
38 | #endif//__cplusplus
39 |
40 | #endif//__fon9_CStrView_h__
41 |
--------------------------------------------------------------------------------
/fon9/Comparable.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/Comparable.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_Comparable_hpp__
4 | #define __fon9_Comparable_hpp__
5 |
6 | namespace fon9 {
7 |
8 | /// \ingroup AlNum
9 | /// - 您的 T 必須有定義:
10 | /// - bool operator==(const T& lhs, const T& rhs);
11 | /// - bool operator< (const T& lhs, const T& rhs);
12 | /// - 然後可透過這裡, 增加:
13 | /// - bool operator!=(const T& lhs, const T& rhs);
14 | /// - bool operator> (const T& lhs, const T& rhs);
15 | /// - bool operator>=(const T& lhs, const T& rhs);
16 | /// - bool operator<=(const T& lhs, const T& rhs);
17 | template
18 | struct Comparable {
19 | inline friend bool operator!=(const T& lhs, const T& rhs) {
20 | return !(lhs == rhs);
21 | }
22 | inline friend bool operator> (const T& lhs, const T& rhs) {
23 | return (rhs < lhs);
24 | }
25 | inline friend bool operator<=(const T& lhs, const T& rhs) {
26 | return !(rhs < lhs);
27 | }
28 | inline friend bool operator>=(const T& lhs, const T& rhs) {
29 | return !(lhs < rhs);
30 | }
31 | };
32 |
33 | } // namespaces
34 | #endif//__fon9_Comparable_hpp__
35 |
--------------------------------------------------------------------------------
/fon9/ConfigUtils.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/ConfigUtils.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/ConfigUtils.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API EnabledYN StrTo(StrView str, EnabledYN defaultValue, const char** endptr) {
8 | const char* pbeg = StrTrimHead(&str).begin();
9 | switch (toupper(str.Get1st())) {
10 | case 'Y':
11 | if (endptr) {
12 | ++pbeg;
13 | if (str.size() >= 3) { // "Yes"
14 | if (toupper(pbeg[0]) == 'E' && toupper(pbeg[1]) == 'S')
15 | pbeg += 2;
16 | }
17 | *endptr = pbeg;
18 | }
19 | return EnabledYN::Yes;
20 | case 'N':
21 | if (endptr) {
22 | ++pbeg;
23 | if (str.size() >= 2) { // "No"
24 | if (toupper(pbeg[0]) == 'O')
25 | ++pbeg;
26 | }
27 | *endptr = pbeg;
28 | }
29 | return EnabledYN{};
30 | case EOF:
31 | if (endptr)
32 | *endptr = pbeg;
33 | return EnabledYN{};
34 | default:
35 | if (endptr)
36 | *endptr = pbeg;
37 | return defaultValue;
38 | }
39 | }
40 |
41 | } // namespaces
42 |
--------------------------------------------------------------------------------
/fon9/CountDownLatch.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/CountDownLatch.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/CountDownLatch.hpp"
4 |
5 | namespace fon9 {
6 |
7 | void CountDownLatch::Wait() {
8 | Locker locker(this->Mutex_);
9 | while (this->Counter_ > 0)
10 | this->Waiter_.Wait(locker);
11 | }
12 | void CountDownLatch::CountDown() {
13 | Locker locker(this->Mutex_);
14 | if (--this->Counter_ > 0)
15 | return;
16 | this->Counter_ = 0;
17 | this->Waiter_.NotifyAll(locker);
18 | }
19 | int CountDownLatch::ForceWakeUp() {
20 | Locker locker(this->Mutex_);
21 | int bfcount = this->Counter_;
22 | this->Counter_ = 0;
23 | this->Waiter_.NotifyAll(locker);
24 | return bfcount;
25 | }
26 | int CountDownLatch::AddCounter(unsigned count) {
27 | Locker locker(this->Mutex_);
28 | int bfcount = this->Counter_;
29 | this->Counter_ += count;
30 | return bfcount;
31 | }
32 |
33 | } // namespace
34 |
--------------------------------------------------------------------------------
/fon9/CountDownLatch.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/CountDownLatch.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_CountDownLatch_hpp__
4 | #define __fon9_CountDownLatch_hpp__
5 | #include "fon9/WaitPolicy.hpp"
6 |
7 | namespace fon9 {
8 |
9 | fon9_WARN_DISABLE_PADDING;
10 | /// \ingroup Thrs
11 | /// 等候指定數量的倒數.
12 | /// 一旦倒數到 0, 就會叫醒所有的等候者, 且以後的等候都會立即返回.
13 | class fon9_API CountDownLatch {
14 | fon9_NON_COPY_NON_MOVE(CountDownLatch);
15 | using Waiter = WaitPolicy_CV;
16 | using Mutex = Waiter::Mutex;
17 | using Locker = typename Waiter::Locker;
18 | Mutex Mutex_;
19 | Waiter Waiter_;
20 | signed Counter_;
21 | public:
22 | /// 建構時指定要倒數的次數.
23 | inline explicit CountDownLatch(unsigned count) : Counter_(static_cast(count)) {
24 | }
25 | /// 等候倒數到0, 才會返回.
26 | /// 這裡不會變動計數器.
27 | void Wait();
28 |
29 | /// 倒數一次, 倒數到0時, 觸發喚醒全部等候者.
30 | void CountDown();
31 |
32 | /// 強迫倒數結束.
33 | /// 返回強制中斷前剩餘倒數次數.
34 | int ForceWakeUp();
35 |
36 | /// 強制增加 Counter.
37 | /// 返回強制增加前剩餘倒數次數.
38 | int AddCounter(unsigned count);
39 | };
40 | fon9_WARN_POP;
41 |
42 | } // namespaces
43 | #endif//__fon9_CountDownLatch_hpp__
44 |
--------------------------------------------------------------------------------
/fon9/CtrlBreakHandler.h:
--------------------------------------------------------------------------------
1 | // \file fon9/CtrlBreakHandler.h
2 | // fon9 console
3 | // \author fonwinz@gmail.com
4 | #ifndef __fon9_CtrlBreakHandler_h__
5 | #define __fon9_CtrlBreakHandler_h__
6 | #include "fon9/sys/Config.h"
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | extern fon9_API const char* fon9_AppBreakMsg;
13 | extern fon9_API void fon9_CAPI_CALL fon9_SetupCtrlBreakHandler(void);
14 |
15 | /// 使用者手動結束程式, 主程式必須使用 while(fon9_AppBreakMsg == NULL) 迴圈;
16 | /// 此處會關閉 stdin; 中斷正在等後使用者輸入的地方.
17 | /// 您必須自行確保 appBreakMsg 在程式 main() 結束前都持續有效!
18 | extern fon9_API void fon9_CAPI_CALL fon9_BreakApp(const char* appBreakMsg);
19 |
20 | #ifdef __cplusplus
21 | }//extern "C"
22 | #endif
23 | #endif//__fon9_CtrlBreakHandler_h__
24 |
--------------------------------------------------------------------------------
/fon9/CyclicBarrier.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/CyclicBarrier.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/CyclicBarrier.hpp"
4 |
5 | namespace fon9 {
6 |
7 | void CyclicBarrier::Wait() {
8 | Locker locker(this->Mutex_);
9 | if (++this->WaitingCount_ < this->ExpectedCount_) {
10 | this->Latch_.Wait(locker);
11 | } else {
12 | this->WaitingCount_ = 0;
13 | this->Latch_.NotifyAll(locker);
14 | }
15 | }
16 |
17 | } // namespace
18 |
--------------------------------------------------------------------------------
/fon9/CyclicBarrier.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/CyclicBarrier.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_CyclicBarrier_hpp__
4 | #define __fon9_CyclicBarrier_hpp__
5 | #include "fon9/WaitPolicy.hpp"
6 |
7 | namespace fon9 {
8 |
9 | /// \ingroup Thrs
10 | /// 當同時等候中的 Threads 到達指定數量時, 則喚醒所有等候者.
11 | /// 喚醒等候者之後, 計數器會歸0, 重複等候邏輯.
12 | class fon9_API CyclicBarrier {
13 | fon9_NON_COPY_NON_MOVE(CyclicBarrier);
14 | using Waiter = WaitPolicy_CV;
15 | using Mutex = Waiter::Mutex;
16 | using Locker = typename Waiter::Locker;
17 | Mutex Mutex_;
18 | Waiter Latch_;
19 | unsigned WaitingCount_;
20 | public:
21 | /// 期待等候的數量.
22 | const unsigned ExpectedCount_;
23 | explicit CyclicBarrier(unsigned expectedCount) : WaitingCount_(0), ExpectedCount_(expectedCount) {
24 | }
25 | /// 當同時等候的Threads到達指定數量時返回.
26 | void Wait();
27 | };
28 |
29 | } // namespaces
30 | #endif//__fon9_CyclicBarrier_hpp__
31 |
--------------------------------------------------------------------------------
/fon9/DecBase.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/DecBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/DecBase.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API uintmax_t GetDecDivisor(DecScaleT scale) {
8 | // 使用 uintmax_t 可以到19位, 但卻無法處理 intmax_t 的負數, 所以這裡必須使用 DecDivisor::Divisor
9 | static constexpr intmax_t dmap[DecScaleMax + 1]{
10 | DecDivisor::Divisor,
11 | DecDivisor::Divisor,
12 | DecDivisor::Divisor,
13 | DecDivisor::Divisor,
14 | DecDivisor::Divisor,
15 | DecDivisor::Divisor,
16 | DecDivisor::Divisor,
17 | DecDivisor::Divisor,
18 | DecDivisor::Divisor,
19 | DecDivisor::Divisor,
20 | DecDivisor::Divisor,
21 | DecDivisor::Divisor,
22 | DecDivisor::Divisor,
23 | DecDivisor::Divisor,
24 | DecDivisor::Divisor,
25 | DecDivisor::Divisor,
26 | DecDivisor::Divisor,
27 | DecDivisor::Divisor,
28 | DecDivisor::Divisor,
29 | };
30 | if (fon9_LIKELY(scale < numofele(dmap)))
31 | return static_cast(dmap[scale]);
32 | Raise("GetDecDivisor(scale > DecScaleMax)");
33 | }
34 |
35 | } // namespaces
36 |
--------------------------------------------------------------------------------
/fon9/DummyMutex.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/DummyMutex.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_DummyMutex_hpp__
4 | #define __fon9_DummyMutex_hpp__
5 | #include "fon9/sys/Config.hpp"
6 |
7 | namespace fon9 {
8 |
9 | class DummyMutex {
10 | fon9_NON_COPY_NON_MOVE(DummyMutex);
11 | public:
12 | DummyMutex() = default;
13 | void lock() {}
14 | void unlock() {}
15 | };
16 |
17 | } // namespaces
18 | #endif//__fon9_DummyMutex_hpp__
19 |
--------------------------------------------------------------------------------
/fon9/ErrC.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/ErrC.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_ErrC_hpp__
4 | #define __fon9_ErrC_hpp__
5 | #include "fon9/sys/Config.hpp"
6 |
7 | fon9_BEFORE_INCLUDE_STD;
8 | #include
9 | fon9_AFTER_INCLUDE_STD;
10 |
11 | namespace fon9 {
12 |
13 | using ErrC = std::error_condition;
14 |
15 | #ifdef fon9_WINDOWS
16 | fon9_API ErrC GetSysErrC(DWORD eno = ::GetLastError());
17 | #else
18 | fon9_API ErrC GetSysErrC(int eno = errno);
19 | #endif
20 |
21 | template
22 | void RevPrint(RevBuffer& rbuf, ErrC errc) {
23 | RevPrint(rbuf, ':', errc.value(), ':', errc.message());
24 | if (errc.category() != std::generic_category())
25 | RevPrint(rbuf, errc.category().name());
26 | }
27 |
28 | } // namespace
29 | #endif//__fon9_ErrC_hpp__
30 |
--------------------------------------------------------------------------------
/fon9/F9cardDevel.h:
--------------------------------------------------------------------------------
1 | // \file fon9/F9cardDevel.h
2 | //
3 | // 用於開發階段, 包含 [量測延遲] 所需的相關檔案.
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __fon9_F9cardDevel_h__
7 | #define __fon9_F9cardDevel_h__
8 |
9 | #ifdef F9CARD
10 | #include "f9/LatencyMeasure.h"
11 | #include "f9/CpuCache.h"
12 | #else
13 | # define f9_LatencyMeasure_Push(locName)
14 | # define f9_DCachePrefetchRd(addr,locality)
15 | # define f9_DCachePrefetchWr(addr,locality)
16 | #endif
17 |
18 | #endif//__fon9_F9cardDevel_h__
19 |
--------------------------------------------------------------------------------
/fon9/FdrNotify.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/FdrNotify.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_FdrNotify_hpp__
4 | #define __fon9_FdrNotify_hpp__
5 | #include "fon9/Fdr.hpp"
6 | #include "fon9/Outcome.hpp"
7 |
8 | #ifdef __linux__
9 | #define fon9_HAVE_EVENTFD
10 | #include
11 | #endif
12 |
13 | namespace fon9 {
14 |
15 | /// \ingroup Misc
16 | /// - Linux: 使用 eventfd() 實現.
17 | /// - 非linux: 使用 pipe() 實現.
18 | class fon9_API FdrNotify {
19 | fon9_NON_COPY_NON_MOVE(FdrNotify);
20 | #ifdef fon9_HAVE_EVENTFD
21 | FdrAuto EventFdr_;
22 | #else
23 | FdrAuto FdrRead_;
24 | FdrAuto FdrWrite_;
25 | #endif
26 | public:
27 | using Result = Result3;
28 |
29 | FdrNotify() {
30 | this->Open();
31 | }
32 | /// 開啟 fd, 若建構時已開啟成功, 不會重新開啟.
33 | Result Open();
34 | /// 喚醒讀取端.
35 | Result Wakeup();
36 | /// 取得讀取端的 fd.
37 | Fdr::fdr_t GetReadFD() const {
38 | #ifdef fon9_HAVE_EVENTFD
39 | return EventFdr_.GetFD();
40 | #else
41 | return FdrRead_.GetFD();
42 | #endif
43 | }
44 | /// 傳回 Wakeup() 呼叫的次數, 並清除計數器.
45 | uint64_t ClearWakeup();
46 | };
47 |
48 | } // namespaces
49 | #endif//__fon9_FdrNotify_hpp__
50 |
--------------------------------------------------------------------------------
/fon9/FileReadAll.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/FileReadAll.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/FileReadAll.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API ReadAllResult OpenReadAll(File& fd, CharVector& fbuf, std::string fname, FileMode fmode) {
8 | File::Result fres;
9 | if (!fname.empty()) {
10 | fres = fd.Open(std::move(fname), fmode);
11 | if (fres.IsError())
12 | return ReadAllResult{"Open", fres.GetError()};
13 | }
14 | fres = fd.GetFileSize();
15 | if (fres.IsError())
16 | return ReadAllResult{"GetFileSize", fres.GetError()};
17 | if (fbuf.alloc(fres.GetResult()) == nullptr)
18 | return ReadAllResult{"Alloc", std::errc::not_enough_memory};
19 | fres = fd.Read(0, fbuf.begin(), fres.GetResult());
20 | if (fres.IsError())
21 | return ReadAllResult{"Read", fres.GetError()};
22 | return ReadAllResult{};
23 | }
24 |
25 | } // namespace
26 |
--------------------------------------------------------------------------------
/fon9/FileReadAll.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/FileReadAll.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_FileReadAll_hpp__
4 | #define __fon9_FileReadAll_hpp__
5 | #include "fon9/buffer/DcQueueList.hpp"
6 | #include "fon9/buffer/FwdBufferList.hpp"
7 | #include "fon9/File.hpp"
8 |
9 | namespace fon9 {
10 |
11 | using ReadAllResult = Result2T;
12 |
13 | /// fname.empty() 則直接使用 fd, 不需要開啟檔案;
14 | fon9_API ReadAllResult OpenReadAll(File& fd, CharVector& fbuf, std::string fname, FileMode fmode);
15 |
16 | template
17 | typename FileT::Result FileReadAll(FileT& fd, PosT& fpos, ConsumerT&& consumer) {
18 | DcQueueList rdbuf;
19 | for (;;) {
20 | FwdBufferNode* node = FwdBufferNode::Alloc(32 * 1024);
21 | auto res = fd.Read(fpos, node->GetDataEnd(), node->GetRemainSize());
22 | if (res.IsError()) {
23 | FreeNode(node);
24 | return res;
25 | }
26 | if (res.GetResult() <= 0) {
27 | FreeNode(node);
28 | return res;
29 | }
30 | fpos += res.GetResult();
31 | node->SetDataEnd(node->GetDataEnd() + res.GetResult());
32 | rdbuf.push_back(node);
33 | if (!consumer(rdbuf, res))
34 | return res;
35 | }
36 | }
37 |
38 | } // namespaces
39 | #endif//__fon9_FileReadAll_hpp__
40 |
--------------------------------------------------------------------------------
/fon9/FlowCounter.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/FlowCounter.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/FlowCounter.hpp"
4 |
5 | namespace fon9 {
6 |
7 | ConfigParser::Result FlowCounterArgs::OnTagValue(StrView tag, StrView& value) {
8 | if (iequals(tag, "Fc"))
9 | return this->OnValue(value);
10 | return ConfigParser::Result::EUnknownTag;
11 | }
12 | ConfigParser::Result FlowCounterArgs::OnValue(StrView& value) {
13 | this->FcCount_ = StrTo(&value, this->FcCount_);
14 | if (StrTrimHead(&value).Get1st() == '/') {
15 | value.SetBegin(value.begin() + 1);
16 | this->FcTimeMS_ = StrTo(&value, this->FcTimeMS_);
17 | }
18 | return value.empty() ? ConfigParser::Result::Success : ConfigParser::Result::EInvalidValue;
19 | }
20 |
21 | } // namespace
22 |
--------------------------------------------------------------------------------
/fon9/HostId.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/HostId.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/HostId.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API HostId LocalHostId_;
8 |
9 | } // namespaces
10 |
--------------------------------------------------------------------------------
/fon9/HostId.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/HostId.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_HostId_hpp__
4 | #define __fon9_HostId_hpp__
5 | #include "fon9/sys/Config.hpp"
6 | #include
7 |
8 | namespace fon9 {
9 |
10 | using HostId = uint32_t;
11 |
12 | /// \ingroup Misc
13 | /// 需在啟動時由使用者設定內容, 在沒設定之前為 LocalHostId_==0.
14 | extern fon9_API HostId LocalHostId_;
15 |
16 | } // namespaces
17 | #endif//__fon9_HostId_hpp__
18 |
--------------------------------------------------------------------------------
/fon9/Outcome.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/Outcome.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/Outcome.hpp"
4 |
5 | namespace fon9 {
6 |
7 | [[noreturn]] fon9_API void RaiseOutcomeException(OutcomeSt st) {
8 | switch (st) {
9 | default:
10 | case OutcomeSt::NoValue: Raise("Outcome NoValue");
11 | case OutcomeSt::Result: Raise("Outcome HasResult");
12 | case OutcomeSt::Error: Raise("Outcome IsError");
13 | }
14 | }
15 |
16 | } // namespace
17 |
--------------------------------------------------------------------------------
/fon9/PassKey.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/PassKey.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/PassKey.hpp"
4 | #include "fon9/StrTo.hpp"
5 |
6 | namespace fon9 {
7 |
8 | static bool defaultPassKeyToPassword(const StrView& passKey, CharVector& password) {
9 | password.assign(passKey);
10 | return false;
11 | }
12 | static FnPassKeyToPassword stFnPassKeyToPassword = defaultPassKeyToPassword;
13 | //--------------------------------------------------------------------------//
14 | fon9_API void SetFnPassKeyToPassword(FnPassKeyToPassword fnPassKeyToPassword) {
15 | stFnPassKeyToPassword = (fnPassKeyToPassword ? fnPassKeyToPassword : defaultPassKeyToPassword);
16 | }
17 |
18 | fon9_API bool PassKeyToPassword(const StrView& passKey, CharVector& password) {
19 | return stFnPassKeyToPassword(passKey, password);
20 | }
21 |
22 | fon9_API unsigned PassKeyToPassNum(const StrView& passKey, unsigned defaultPassNum) {
23 | CharVector password;
24 | if (PassKeyToPassword(passKey, password))
25 | return StrTo(ToStrView(password), defaultPassNum);
26 | return defaultPassNum;
27 | }
28 |
29 | } // namesapce fon9;
30 |
--------------------------------------------------------------------------------
/fon9/PassKey.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/PassKey.hpp
2 | //
3 | // PassIdMgr: 協助管理密碼設定
4 | // 在系統的設定裡面使用 PassKey="PassId/Salt"; 可以避免在設定中出現[明碼].
5 | //
6 | // \author fonwinz@gmail.com
7 | #ifndef __fon9_PassKey_hpp__
8 | #define __fon9_PassKey_hpp__
9 | #include "fon9/CharVector.hpp"
10 |
11 | namespace fon9 {
12 |
13 | typedef bool (*FnPassKeyToPassword)(const StrView& passKey, CharVector& password);
14 |
15 | /// \ingroup Misc
16 | /// 設定透過 passKey 取得 password 的功能.
17 | extern fon9_API void SetFnPassKeyToPassword(FnPassKeyToPassword fnPassKeyToPassword);
18 |
19 | /// \ingroup Misc
20 | /// 透過 passKey 取得 password.
21 | /// 預設: password = passKey, 返回 false;
22 | extern fon9_API bool PassKeyToPassword(const StrView& passKey, CharVector& password);
23 |
24 | /// \ingroup Misc
25 | /// 透過 passKey 取得數字密碼.
26 | /// \code
27 | /// if (PassKeyToPassword()) return StrTo(password, defaultPassNum);
28 | /// else return defaultPassNum;
29 | /// \endcode
30 | extern fon9_API unsigned PassKeyToPassNum(const StrView& passKey, unsigned defaultPassNum);
31 |
32 | } // namespace
33 | #endif//__fon9_PassKey_hpp__
34 |
--------------------------------------------------------------------------------
/fon9/Random.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/Random.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_Random_hpp__
4 | #define __fon9_Random_hpp__
5 | #include "fon9/sys/Config.hpp"
6 |
7 | fon9_BEFORE_INCLUDE_STD;
8 | #include
9 | fon9_AFTER_INCLUDE_STD;
10 |
11 | namespace fon9 {
12 |
13 | /// \ingroup Misc
14 | /// 在 dst[0..dstSize-1] 填入亂數.
15 | fon9_API void RandomBytes(void* dst, size_t dstSize);
16 |
17 | /// \ingroup Misc
18 | /// 在 dst[0..dstSize) 任意填入以下 ASCII 字元, 不包含 EOS.
19 | /// - '0'..'9', 'A'..'Z', 'a'..'z'
20 | /// - '+', '-', '*', '/', '%', '@'
21 | /// - '!', '$', '&', '_', '?', '^'
22 | fon9_API void RandomChars(char* dst, size_t dstSize);
23 |
24 | /// \ingroup Misc
25 | /// = RandomChars(dst, dstSize-1); dst[dstSize-1] = 0;
26 | inline void RandomString(char* dst, size_t dstSize) {
27 | if (fon9_LIKELY(dstSize > 0)) {
28 | dst[dstSize - 1] = 0;
29 | if (fon9_LIKELY(dstSize > 1))
30 | RandomChars(dst, dstSize - 1);
31 | }
32 | }
33 |
34 | /// \ingroup Misc
35 | /// 取得一個 thrdad_local 的 std::default_random_engine
36 | fon9_API std::default_random_engine& GetRandomEngine();
37 |
38 | } // namespaces
39 | #endif//__fon9_Random_hpp__
40 |
--------------------------------------------------------------------------------
/fon9/SimpleFactory.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/SimpleFactory.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/SimpleFactory.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API void SimpleFactoryPrintDupName(StrView name, unsigned priority) {
8 | fprintf(stderr, "SimpleFactoryRegister: priority=%u, dup name: %s\n", priority, name.ToString().c_str());
9 | }
10 |
11 | } // namespaces
12 |
--------------------------------------------------------------------------------
/fon9/SleepPolicy.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/SleepPolicy.hpp
2 | /// \brief 提供各種 [睡一會兒] 的策略
3 | /// \author fonwinz@gmail.com
4 | #ifndef __fon9_SleepPolicy_hpp__
5 | #define __fon9_SleepPolicy_hpp__
6 | #include "fon9/sys/Config.hpp"
7 |
8 | fon9_BEFORE_INCLUDE_STD;
9 | #include
10 | fon9_AFTER_INCLUDE_STD;
11 |
12 | namespace fon9 {
13 |
14 | /// \ingroup Thrs
15 | /// 不睡覺,立即返回.
16 | class BusySleepPolicy {
17 | public:
18 | /// 不睡, 立即返回.
19 | static void Sleep() {
20 | }
21 | /// 因為不睡, 所以不用喚醒: do nothing.
22 | static void WakeUp() {
23 | }
24 | };
25 |
26 | /// \ingroup Thrs
27 | /// 用 std::this_thread::yield() 睡覺.
28 | class YieldSleepPolicy {
29 | public:
30 | /// 利用 std::this_thread::yield() 睡覺, 然後立即返回.
31 | static void Sleep() {
32 | std::this_thread::yield();
33 | }
34 | /// 等候 std::this_thread::yield() 返回自然會醒, 所以這裡: do nothing.
35 | static void WakeUp() {
36 | }
37 | };
38 |
39 | /// \ingroup Thrs
40 | /// 用 std::this_thread::sleep_for() 睡覺.
41 | /// \tparam ns 沉睡時間(10^-9 秒)
42 | template
43 | class NanoSleepPolicy {
44 | public:
45 | /// 沉睡 ns (10^-9 秒), 然後返回, 睡醒前無法中斷.
46 | static void Sleep() {
47 | std::this_thread::sleep_for(std::chrono::nanoseconds(ns));
48 | }
49 | /// 等時間到自然會醒, 沒有喚醒功能: do nothing.
50 | static void WakeUp() {
51 | }
52 | };
53 |
54 | } // namespaces
55 | #endif//__fon9_SleepPolicy_hpp__
56 |
--------------------------------------------------------------------------------
/fon9/SpinMutex.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/SpinMutex.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_SpinMutex_hpp__
4 | #define __fon9_SpinMutex_hpp__
5 | #include "fon9/sys/Config.hpp"
6 | #include "fon9/SleepPolicy.hpp"
7 | #include
8 |
9 | namespace fon9 {
10 |
11 | /// \ingroup Thrs
12 | /// 使用 spin 機制模擬 mutex.
13 | /// 您必須提供 SleepPolicy::Sleep() 在鎖不住時, 睡一會兒.
14 | /// \tparam SleepPolicy 參考 fon9/SleepPolicy.hpp: BusySleepPolicy, YieldSleepPolicy, NanoSleepPolicy...
15 | template
16 | class SpinMutex : private SleepPolicy {
17 | fon9_NON_COPYABLE(SpinMutex);
18 | std::atomic_flag Mx_ = ATOMIC_FLAG_INIT;
19 | public:
20 | using SleepPolicy::SleepPolicy;
21 | SpinMutex() : SleepPolicy{} {
22 | }
23 |
24 | /// 當鎖不住時, 利用 SleepPolicy::Sleep() 睡一會兒, 然後重新嘗試再鎖一次, 直到鎖成功才返回.
25 | void lock() {
26 | while (!try_lock())
27 | this->Sleep();
28 | }
29 |
30 | /// 嘗試鎖住, 立即即返回: 鎖成功傳回 true, 無法鎖住傳回 false.
31 | bool try_lock() {
32 | return !this->Mx_.test_and_set(std::memory_order_acquire);
33 | }
34 |
35 | /// 解鎖, 不檢查現在鎖的狀態, 所以您必須自行確定: 之前有鎖成功.
36 | void unlock() {
37 | this->Mx_.clear(std::memory_order_release);
38 | this->WakeUp();
39 | }
40 |
41 | void Wait() {
42 | this->Sleep();
43 | }
44 | };
45 |
46 | using SpinBusy = SpinMutex;
47 |
48 | } // namespaces
49 | #endif//__fon9_SpinMutex_hpp__
50 |
--------------------------------------------------------------------------------
/fon9/ThreadId.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/ThreadId.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/ThreadId.hpp"
4 | #include "fon9/ToStr.hpp"
5 |
6 | #ifndef fon9_WINDOWS
7 | #include //For SYS_xxx definitions
8 | inline static fon9::ThreadId::IdType GetCurrentThreadId() {
9 | // return static_cast(pthread_self());//pthread_self()用的是一個內部指標, 與 OS 的 thread-id 無關, 所以並不適合.
10 | return static_cast(::syscall(SYS_gettid));
11 | // return static_cast(syscall(__NR_gettid));
12 | }
13 | #endif
14 |
15 | namespace fon9 {
16 |
17 | const thread_local ThreadId ThisThread_;
18 |
19 | ThreadId::ThreadId() : ThreadId_{::GetCurrentThreadId()} {
20 | char* const pend = this->ThreadIdStr_ + sizeof(this->ThreadIdStr_);
21 | char* pout = UIntToStrRev(pend, this->ThreadId_);
22 | size_t wlen = static_cast(pend - pout);
23 | while (++wlen <= 5)
24 | *--pout = ' ';
25 | *--pout = ' ';
26 | this->ThreadIdStrWidth_ = static_cast(wlen);
27 | memmove(this->ThreadIdStr_, pout, wlen);
28 | *(this->ThreadIdStr_ + wlen) = '\0';
29 | }
30 |
31 | fon9_API const ThreadId& GetThisThreadId() {
32 | return ThisThread_;
33 | }
34 |
35 | } // namespaces
36 |
--------------------------------------------------------------------------------
/fon9/ThreadId.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/ThreadId.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_ThreadId_hpp__
4 | #define __fon9_ThreadId_hpp__
5 | #include "fon9/StrView.hpp"
6 |
7 | namespace fon9 {
8 |
9 | /// \ingroup Thrs
10 | /// this thread 的基本資料.
11 | struct ThreadId {
12 | using IdType = uintptr_t;
13 | /// Windows=GetCurrentThreadId(), Linux=pthread_self()
14 | IdType ThreadId_;
15 | /// ThreadIdStr_ 不含 EOS 的長度.
16 | uint8_t ThreadIdStrWidth_;
17 | /// ThreadId_ 轉成字串: 預設 = 從前方算起 " nnnnn"(10進位字串, 長度最少為6包含開頭1空白), 若超過5碼, 則自動擴展.
18 | /// 必定會有 EOS, 但不包含在 ThreadIdStrWidth_.
19 | char ThreadIdStr_[15];
20 |
21 | ThreadId();
22 |
23 | StrView GetThreadIdStr() const {
24 | return StrView{this->ThreadIdStr_, this->ThreadIdStrWidth_};
25 | }
26 | };
27 |
28 | /// \ingroup Thrs
29 | /// Windows 不能使用 fon9_API + thread_local, 所以必須使用 GetThisThreadId() 取得.
30 | extern const thread_local ThreadId ThisThread_;
31 |
32 | /// \ingroup Thrs
33 | /// 取得 this_thread 的 ThreadId: 可藉此取得 ThreadId_, ThreadIdStr_.
34 | fon9_API const ThreadId& GetThisThreadId();
35 |
36 | } // namespaces
37 | #endif//__fon9_ThreadId_hpp__
38 |
--------------------------------------------------------------------------------
/fon9/ThreadTools.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/ThreadTools.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/ThreadTools.hpp"
4 |
5 | namespace fon9 {
6 |
7 | #ifdef fon9_WINDOWS
8 |
9 | const DWORD MS_VC_EXCEPTION = 0x406D1388;
10 |
11 | fon9_WARN_DISABLE_PADDING
12 | #pragma pack(push,8)
13 | typedef struct tagTHREADNAME_INFO
14 | {
15 | DWORD dwType; // Must be 0x1000.
16 | LPCSTR szName; // Pointer to name (in user addr space).
17 | DWORD dwThreadID; // Thread ID (-1=caller thread).
18 | DWORD dwFlags; // Reserved for future use, must be zero.
19 | } THREADNAME_INFO;
20 | #pragma pack(pop)
21 | fon9_WARN_POP
22 |
23 | void SetCurrentThreadName(const char* threadName) {
24 | THREADNAME_INFO info;
25 | info.dwType = 0x1000;
26 | info.szName = threadName;
27 | info.dwThreadID = (DWORD)-1;
28 | info.dwFlags = 0;
29 | #pragma warning(push)
30 | #pragma warning(disable: 6320 6322)
31 | __try {
32 | RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
33 | }
34 | __except (EXCEPTION_EXECUTE_HANDLER) {
35 | }
36 | #pragma warning(pop)
37 | }
38 | #endif
39 |
40 | } // namespaces
41 |
--------------------------------------------------------------------------------
/fon9/ThreadTools.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/ThreadTools.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_ThreadTools_hpp__
4 | #define __fon9_ThreadTools_hpp__
5 | #include "fon9/sys/Config.hpp"
6 |
7 | fon9_BEFORE_INCLUDE_STD
8 | #include
9 | fon9_AFTER_INCLUDE_STD
10 |
11 | namespace fon9 {
12 |
13 | inline void JoinThread(std::thread& thr) {
14 | if (thr.joinable())
15 | thr.join();
16 | }
17 |
18 | template
19 | inline void JoinThreads(ThreadContainer& thrs) {
20 | for (std::thread& thr : thrs)
21 | JoinThread(thr);
22 | }
23 |
24 | inline void JoinOrDetach(std::thread& thr) {
25 | if (thr.get_id() == std::this_thread::get_id())
26 | thr.detach();
27 | else
28 | if (thr.joinable())
29 | thr.join();
30 | }
31 |
32 | template
33 | inline void JoinOrDetach(ThreadContainer& thrs) {
34 | for (std::thread& thr : thrs)
35 | JoinOrDetach(thr);
36 | }
37 |
38 | /// 設定 ThreadName.
39 | /// 可讓 M$ VS 開發環境, 在 debug 時的 Threads 視窗, 清楚看出各個 threads 的用途.
40 | #ifdef fon9_WINDOWS
41 | fon9_API void SetCurrentThreadName(const char* threadName);
42 | #else
43 | inline void SetCurrentThreadName(const char* threadName) {
44 | (void)threadName;
45 | }
46 | #endif
47 |
48 | } // namespace fon9
49 | #endif//__fon9_ThreadTools_hpp__
50 |
--------------------------------------------------------------------------------
/fon9/Tools.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/Tools.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_Tools_hpp__
4 | #define __fon9_Tools_hpp__
5 | #include "fon9/Outcome.hpp"
6 | #include "fon9/StrView.hpp"
7 |
8 | namespace fon9 {
9 |
10 | enum class HowWait {
11 | Unknown,
12 | Block,
13 | Yield,
14 | Busy,
15 | };
16 | inline bool IsBlockWait(HowWait value) {
17 | return value <= HowWait::Block;
18 | }
19 | fon9_API HowWait StrToHowWait(StrView value);
20 | fon9_API StrView HowWaitToStr(HowWait value);
21 |
22 | /// \ingroup Misc
23 | /// 設定「現在 thread」的 CPU 綁定.
24 | /// \retval Result3::kNoResult() cpuAffinity < 0: 不綁定.
25 | /// \retval Result3::kSuccess() cpuAffinity >=0: 綁定成功.
26 | /// \retval retval.IsError() 綁定失敗原因.
27 | fon9_API Result3 SetCpuAffinity(int cpuAffinity);
28 |
29 | /// \ingroup Misc
30 | /// 將 big5 字串轉成 utf8.
31 | /// 轉換後 outbuf 尾端不包含 EOS.
32 | fon9_API size_t Big5ToUtf8NoEOS(StrView strBig5, char* outbuf, size_t outbufsz);
33 | /// \ingroup Misc
34 | /// 將 big5 字串轉成 utf8.
35 | /// 轉換後 outbuf 尾端如果還有空間, 則會填入一個 EOS.
36 | inline size_t Big5ToUtf8EOS(const StrView& strBig5, char* outbuf, size_t outbufsz) {
37 | size_t retval = Big5ToUtf8NoEOS(strBig5, outbuf, outbufsz);
38 | if (retval < outbufsz)
39 | outbuf[retval] = '\0';
40 | return retval;
41 | }
42 |
43 | } // namespace
44 | #endif//__fon9_Tools_hpp__
45 |
--------------------------------------------------------------------------------
/fon9/TsAppend.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/TsAppend.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/TsAppend.hpp"
4 | #include "fon9/BitvFixedInt.hpp"
5 |
6 | namespace fon9 {
7 |
8 | fon9_API void TsAppend(AsyncFileAppender& pklog, TimeStamp now,
9 | const void* pkptr, uint16_t pksz) {
10 | size_t kSaveSize = pksz + sizeof(now) + sizeof(pksz);
11 | RevBufferNode* rbuf{RevBufferNode::Alloc(kSaveSize)};
12 | fon9::byte* pbuf = rbuf->GetDataBegin() - kSaveSize;
13 | rbuf->SetPrefixUsed(pbuf);
14 | *pbuf = fon9_BitvT_TimeStamp_Orig7; // 0xe0
15 | ToBitvFixedRev(reinterpret_cast(pbuf) + sizeof(now), now.GetOrigValue());
16 | PutBigEndian(pbuf + sizeof(now), pksz);
17 | memcpy(pbuf + sizeof(now) + sizeof(pksz), pkptr, pksz);
18 | pklog.Append(rbuf);
19 | }
20 |
21 | } // namespaces
22 |
--------------------------------------------------------------------------------
/fon9/TsAppend.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/TsAppend.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_TsAppend_hpp__
4 | #define __fon9_TsAppend_hpp__
5 | #include "fon9/FileAppender.hpp"
6 | #include "fon9/TimeStamp.hpp"
7 |
8 | namespace fon9 {
9 |
10 | /// 將 pkptr 加入 pklog 尾端, 格式如下:
11 | /// - 0xe0 (fon9_BitvT_TimeStamp_Orig7)
12 | /// - 收到封包的時間: EpochTime(UTC).us: 7 bytes, BigEndian
13 | /// - 封包大小 pksz: 2 bytes, BigEndian
14 | /// - 封包內容 pkptr;
15 | fon9_API void TsAppend(AsyncFileAppender& pklog, TimeStamp now,
16 | const void* pkptr, uint16_t pksz);
17 |
18 | } // namespaces
19 | #endif//__fon9_TsAppend_hpp__
20 |
--------------------------------------------------------------------------------
/fon9/TsReceiver.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/TsReceiver.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/TsReceiver.hpp"
4 | #include "fon9/BitvDecode.hpp"
5 |
6 | namespace fon9 {
7 |
8 | TsReceiver::~TsReceiver() {
9 | }
10 | bool TsReceiver::FeedBuffer(DcQueue& rxbuf) {
11 | char peekbuf[0x10000];
12 | PkszT pksz;
13 | TimeStamp pktm;
14 | while (auto pkptr = static_cast(rxbuf.Peek(peekbuf, kHeadSize))) {
15 | if (fon9_UNLIKELY(*pkptr != fon9_BitvT_TimeStamp_Orig7))
16 | rxbuf.PopUnknownChar(fon9_BitvT_TimeStamp_Orig7);
17 | else {
18 | pktm.SetOrigValue(GetPackedBigEndian(pkptr + 1, sizeof(pktm) - 1));
19 | pksz = GetBigEndian(pkptr + sizeof(pktm));
20 | pkptr = static_cast(rxbuf.Peek(peekbuf, pksz + kHeadSize));
21 | if (fon9_UNLIKELY(pkptr == nullptr)) // rxbuf 資料不足.
22 | break;
23 | bool isCont = this->OnPkReceived(pktm, pkptr + kHeadSize, pksz);
24 | rxbuf.PopConsumed(pksz + kHeadSize);
25 | if (!isCont)
26 | return false;
27 | }
28 | }
29 | return true;
30 | }
31 |
32 | } // namespaces
33 |
--------------------------------------------------------------------------------
/fon9/TsReceiver.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/TsReceiver.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_TsReceiver_hpp__
4 | #define __fon9_TsReceiver_hpp__
5 | #include "fon9/buffer/DcQueue.hpp"
6 | #include "fon9/TimeStamp.hpp"
7 |
8 | namespace fon9 {
9 |
10 | /// \ingroup Misc.
11 | /// 用來解析使用 TsAppend 寫入的封包.
12 | class fon9_API TsReceiver {
13 | fon9_NON_COPY_NON_MOVE(TsReceiver);
14 |
15 | public:
16 | using PkszT = uint16_t;
17 | enum : size_t {
18 | kHeadSize = sizeof(TimeStamp) + sizeof(PkszT)
19 | };
20 |
21 | TsReceiver() = default;
22 | virtual ~TsReceiver();
23 |
24 | /// 收到的訊息透過這裡處理.
25 | /// - 返回時機: rxbuf 用完, 或 rxbuf 剩餘資料不足一個封包.
26 | ///
27 | /// \retval false 呼叫 OnPkReceived() 時返回 false, 中斷 FeedBuffer();
28 | /// \retval true rxbuf 資料不足, 或已解析完畢.
29 | bool FeedBuffer(DcQueue& rxbuf);
30 |
31 | protected:
32 | /// 當收到封包時透過這裡通知衍生者.
33 | /// static_cast(pk) - kHeadSize 必定為 head + pk 的內容.
34 | ///
35 | /// \retval false 結束 FeedBuffer();
36 | /// \retval true 繼續 FeedBuffer();
37 | virtual bool OnPkReceived(TimeStamp pktm, const void* pk, PkszT pksz) = 0;
38 | };
39 |
40 | } // namespaces
41 | #endif//__fon9_TsReceiver_hpp__
42 |
--------------------------------------------------------------------------------
/fon9/Unaligned.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/Unaligned.hpp
2 | ///
3 | /// 存取沒有[記憶體對齊]的資料.
4 | ///
5 | /// - 直接存取沒有[記憶體對齊]的資料, 某些CPU可能會 Bus error,
6 | /// 所以使用 fon9::GetUnaligned(); fon9::PutUnaligned(); 支援這類情形.
7 | /// - 直接使用 memcpy()? 因為較新的 compiler 都能最佳化 memcpy(dst,src,固定大小);
8 | /// 但是如果是 non-POD? 用 memcpy() 是否會有副作用?
9 | ///
10 | /// \author fonwinz@gmail.com
11 | #ifndef __fon9_Unaligned_hpp__
12 | #define __fon9_Unaligned_hpp__
13 | #include
14 |
15 | namespace fon9 {
16 |
17 | #if defined(_MSC_VER) && defined(_WIN64)
18 | template
19 | static inline T GetUnaligned(const T __unaligned* address) {
20 | return *address;
21 | }
22 | template
23 | static inline void PutUnaligned(T __unaligned* address, T value) {
24 | *address = value;
25 | }
26 | #else
27 | template
28 | static inline T GetUnaligned(const T* address) {
29 | T v;
30 | memcpy(&v, address, sizeof(T));
31 | return v;
32 | }
33 | template
34 | static inline void PutUnaligned(T* address, T value) {
35 | memcpy(address, &value, sizeof(value));
36 | }
37 | #endif
38 |
39 | } // namespace
40 | #endif//__fon9_Unaligned_hpp__
41 |
--------------------------------------------------------------------------------
/fon9/auth/PolicyAgent.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/PolicyAgent.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_auth_PolicyAgent_hpp__
4 | #define __fon9_auth_PolicyAgent_hpp__
5 | #include "fon9/auth/PolicyTree.hpp"
6 | #include "fon9/seed/MaTree.hpp"
7 |
8 | namespace fon9 { namespace auth {
9 |
10 | class fon9_API PolicyAgent : public seed::NamedSapling {
11 | fon9_NON_COPY_NON_MOVE(PolicyAgent);
12 | using base = seed::NamedSapling;
13 |
14 | public:
15 | template
16 | PolicyAgent(PolicyTreeSP sapling, NamedSeedArgsT&&... namedSeedArgs)
17 | : base(std::move(sapling), std::forward(namedSeedArgs)...) {
18 | }
19 |
20 | bool LinkStorage(const InnDbfSP& storage, InnRoomSize minRoomSize) {
21 | if (storage)
22 | return storage->LinkTable(&this->Name_, *static_cast(this->Sapling_.get()), minRoomSize);
23 | return false;
24 | }
25 | };
26 |
27 | } } // namespaces
28 | #endif//__fon9_auth_PolicyAgent_hpp__
29 |
--------------------------------------------------------------------------------
/fon9/auth/PolicyMaster.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/PolicyMaster.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/auth/PolicyMaster.hpp"
4 |
5 | namespace fon9 { namespace auth {
6 |
7 | MasterPolicyItem::MasterPolicyItem(const StrView& policyId, MasterPolicyTreeSP owner)
8 | : base{policyId}
9 | , OwnerMasterTree_{std::move(owner)} {
10 | }
11 | seed::TreeSP MasterPolicyItem::GetSapling() {
12 | return this->DetailSapling_;
13 | }
14 | void MasterPolicyItem::SetRemoved(PolicyTable&) {
15 | this->DetailSapling_.reset();
16 | }
17 |
18 | } } // namespaces
19 |
--------------------------------------------------------------------------------
/fon9/auth/PolicyTree.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/PolicyTree.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_auth_PolicyTree_hpp__
4 | #define __fon9_auth_PolicyTree_hpp__
5 | #include "fon9/auth/PolicyTable.hpp"
6 | #include "fon9/seed/Tree.hpp"
7 |
8 | namespace fon9 { namespace auth {
9 |
10 | class fon9_API PolicyTree : public seed::Tree, public PolicyTable {
11 | fon9_NON_COPY_NON_MOVE(PolicyTree);
12 | using base = seed::Tree;
13 | struct PodOp;
14 | struct TreeOp;
15 |
16 | public:
17 | using base::base;
18 |
19 | /// 預設使用底下 Layout1 建構:
20 | /// - KeyField = seed::FieldCharVector(keyName)
21 | /// - Tab = {tabName, fields}
22 | /// - 若上述 Layout 不符, 您也可以直接使用 seed::Tree 的建構參數.
23 | PolicyTree(std::string tabName, std::string keyName, seed::Fields&& fields,
24 | seed::TabFlag tabFlags = seed::TabFlag::Writable | seed::TabFlag::NoSapling);
25 |
26 | virtual void OnTreeOp(seed::FnTreeOp fnCallback) override;
27 | virtual void OnParentSeedClear() override;
28 | };
29 | using PolicyTreeSP = seed::TreeSPT;
30 |
31 | } } // namespaces
32 | #endif//__fon9_auth_PolicyTree_hpp__
33 |
--------------------------------------------------------------------------------
/fon9/auth/RoleMgr.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/RoleMgr.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_auth_RoleMgr_hpp__
4 | #define __fon9_auth_RoleMgr_hpp__
5 | #include "fon9/auth/PolicyAgent.hpp"
6 |
7 | namespace fon9 { namespace auth {
8 |
9 | /// \ingroup auth
10 | /// 使用者 **角色** 管理員.
11 | /// - 透過 RoleId 取得各個 Policy 的設定.
12 | /// - RoleMgr 是一種特殊的 Policy Agent, 由 AuthMgr 在建構時主動加入.
13 | /// - 每個 RoleItem 包含一個 PolicyKeys;
14 | class fon9_API RoleMgr : public PolicyAgent {
15 | fon9_NON_COPY_NON_MOVE(RoleMgr);
16 | using base = PolicyAgent;
17 |
18 | public:
19 | RoleMgr(std::string name);
20 |
21 | enum GetRoleMode {
22 | /// 清除 res.PolicyKeys_, 取得新的設定;
23 | GetRoleMode_Renew,
24 | /// 保留 res.PolicyKeys_, 增加 res.PolicyKeys_ 不存在的設定;
25 | GetRoleMode_Append,
26 | /// 保留 res.PolicyKeys_, 新的 Policy 若已存在則取代, 若不存在則新增;
27 | GetRoleMode_Replace,
28 | };
29 | bool GetRole(StrView roleId, RoleConfig& res, GetRoleMode mode);
30 |
31 | bool LinkStorage(const InnDbfSP& storage) {
32 | return base::LinkStorage(storage, 128);
33 | }
34 | };
35 |
36 | } } // namespaces
37 | #endif//__fon9_auth_RoleMgr_hpp__
38 |
--------------------------------------------------------------------------------
/fon9/auth/SaslScramSha256.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/SaslScramSha256.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/auth/SaslScramSha256.hpp"
4 |
5 | namespace fon9 { namespace auth {
6 |
7 | } } // namespaces
8 |
--------------------------------------------------------------------------------
/fon9/auth/SaslScramSha256.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/SaslScramSha256.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_auth_SaslScramSha256_hpp__
4 | #define __fon9_auth_SaslScramSha256_hpp__
5 | #include "fon9/crypto/Sha256.hpp"
6 | #include "fon9/auth/SaslScram.hpp"
7 |
8 | namespace fon9 { namespace auth {
9 |
10 | fon9_API_TEMPLATE_CLASS(SaslScramSha256, SaslScram, crypto::Sha256);
11 |
12 | } } // namespaces
13 | #endif//__fon9_auth_SaslScramSha256_hpp__
14 |
--------------------------------------------------------------------------------
/fon9/auth/SaslScramSha256Client.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/SaslScramSha256Client.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_auth_SaslScramSha256Client_hpp__
4 | #define __fon9_auth_SaslScramSha256Client_hpp__
5 | #include "fon9/auth/SaslClient.hpp"
6 |
7 | namespace fon9 { namespace auth {
8 |
9 | fon9_API SaslClientSP SaslScramSha256ClientCreator(const StrView& authz, const StrView& authc, const StrView& pass);
10 | fon9_API SaslClientSP SaslScramSha256ClientCreator_ChgPass(const StrView& authz, const StrView& authc, const StrView& oldPass, const StrView& newPass);
11 |
12 | } } // namespaces
13 | #endif//__fon9_auth_SaslScramSha256Client_hpp__
14 |
--------------------------------------------------------------------------------
/fon9/auth/SaslScramSha256Server.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/auth/SaslScramSha256Server.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/auth/SaslScramSha256Server.hpp"
4 |
5 | namespace fon9 { namespace auth {
6 |
7 | class AA_SCRAM_SHA_256 : public AuthAgent {
8 | fon9_NON_COPY_NON_MOVE(AA_SCRAM_SHA_256);
9 | using base = AuthAgent;
10 | public:
11 | UserMgrSP UserMgr_;
12 | AA_SCRAM_SHA_256(const seed::MaTreeSP& /*maTree*/, std::string name, UserMgrSP userMgr)
13 | : base{std::move(name)}
14 | , UserMgr_{std::move(userMgr)} {
15 | }
16 | AuthSessionSP CreateAuthSession(AuthMgrSP authMgr, FnOnAuthVerifyCB cb) override {
17 | return new AuthSession_SaslScramSha256(authMgr, std::move(cb), this->UserMgr_);
18 | }
19 | };
20 |
21 | fon9_API UserMgrSP PlantScramSha256(AuthMgr& authMgr) {
22 | if (UserMgrSP userMgr = UserMgr::Plant(authMgr, "UserSha256", &PassRec::HashPass)) {
23 | if (authMgr.Agents_->Plant("AA_SCRAM_SHA_256.Plant", "AA_SCRAM_SHA_256", userMgr))
24 | return userMgr;
25 | authMgr.Agents_->Remove(&userMgr->Name_);
26 | }
27 | return nullptr;
28 | }
29 |
30 | } } // namespaces
31 |
--------------------------------------------------------------------------------
/fon9/buffer/BufferNode.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/buffer/BufferNode.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/buffer/BufferNode.hpp"
4 |
5 | namespace fon9 {
6 |
7 | BufferNodeVirtual::~BufferNodeVirtual() {
8 | }
9 |
10 | fon9_API void FreeNode(BufferNode* node) {
11 | switch (node->GetNodeType()) {
12 | case BufferNodeType::Data:
13 | break;
14 | case BufferNodeType::Virtual:
15 | BufferNodeVirtual* vnode = static_cast(node);
16 | auto blksz = vnode->BlockSize_;
17 | vnode->~BufferNodeVirtual();
18 | // 有 vtbl, 所以 free 的對象必須是: vnode (而不是 node); (void*)node 不一定與 (void*)vnode 相等.
19 | MemBlock::FreeBlock(vnode, blksz);
20 | return;
21 | }
22 | MemBlock::FreeBlock(node, node->BlockSize_);
23 | }
24 |
25 | } // namespaces
26 |
--------------------------------------------------------------------------------
/fon9/buffer/BufferNodeWaiter.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/BufferNodeWaiter.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/buffer/BufferNodeWaiter.hpp"
4 |
5 | namespace fon9 {
6 |
7 | BufferNodeWaiter::~BufferNodeWaiter() {
8 | }
9 | BufferNodeWaiter* BufferNodeWaiter::Alloc(CountDownLatch& waiter) {
10 | BufferNodeWaiter* res = base::Alloc(0, StyleFlag::AllowCrossing);
11 | res->Waiter_ = &waiter;
12 | return res;
13 | }
14 | void BufferNodeWaiter::OnBufferConsumed() {
15 | this->Waiter_->CountDown();
16 | }
17 | void BufferNodeWaiter::OnBufferConsumedErr(const ErrC&) {
18 | this->Waiter_->CountDown();
19 | }
20 |
21 | } // namespaces
22 |
--------------------------------------------------------------------------------
/fon9/buffer/RevBuffer.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/buffer/RevBuffer.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/buffer/RevBuffer.hpp"
4 |
5 | namespace fon9 {
6 |
7 | void RevBuffer::ForVtblInLib() {
8 | }
9 | char* RevBufferFixedMem::OnRevBufferAlloc(size_t) {
10 | Raise("RevBufferFixedMem overflow");
11 | }
12 |
13 | } // namespace
14 |
--------------------------------------------------------------------------------
/fon9/buffer/RevBufferList.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/buffer/RevBufferList.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/buffer/RevBufferList.hpp"
4 |
5 | namespace fon9 {
6 |
7 | char* RevBufferList::OnRevBufferAlloc(size_t sz) {
8 | this->SetFrontNodeUsed();
9 | this->ResetMemPtr(this->Builder_.NewFront(sz));
10 | return this->MemCurrent_;
11 | }
12 |
13 | } // namespace
14 |
--------------------------------------------------------------------------------
/fon9/fix/FixBase.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fix/FixBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fix/FixBase.hpp"
4 |
5 | namespace fon9 { namespace fix {
6 |
7 | } } // namespaces
8 |
--------------------------------------------------------------------------------
/fon9/fix/FixConfig.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fix/FixConfig.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fix/FixConfig.hpp"
4 |
5 | namespace fon9 { namespace fix {
6 |
7 | const FixMsgTypeConfig* FixConfig::Get(StrView msgType) const {
8 | if (fon9_LIKELY(msgType.size() == 1)) {
9 | int idx = Alpha2Seq(*msgType.begin());
10 | if (0 <= idx && idx < static_cast(numofele(this->Configs_)))
11 | return &this->Configs_[idx];
12 | }
13 | ConfigMap::const_iterator ifind = this->ConfigMap_.find(CharVector::MakeRef(msgType));
14 | return(ifind == this->ConfigMap_.end() ? nullptr : &ifind->second);
15 | }
16 | FixMsgTypeConfig& FixConfig::Fetch(StrView msgType) {
17 | if (fon9_LIKELY(msgType.size() == 1)) {
18 | int idx = Alpha2Seq(*msgType.begin());
19 | if (0 <= idx && idx < static_cast(numofele(this->Configs_)))
20 | return this->Configs_[idx];
21 | }
22 | return this->ConfigMap_.kfetch(CharVector{msgType}).second;
23 | }
24 |
25 | } } // namespaces
26 |
--------------------------------------------------------------------------------
/fon9/fix/IoFixSender.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fix/IoFixSender.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fix/IoFixSender.hpp"
4 |
5 | namespace fon9 { namespace fix {
6 |
7 | IoFixSender::~IoFixSender() {
8 | }
9 | void IoFixSender::OnSendFixMessage(const Locker& lk, BufferList buf) {
10 | assert(lk.owns_lock()); (void)lk;// FixRecorder 仍在鎖定狀態!
11 | if (io::Device* dev = this->Device_.get()) {
12 | // 使用 SendASAP() 一定會 low latency 嗎?
13 | // 因為會立即呼叫 send() or WSASend(), 可能會花不少時間.
14 | // - 這段時間如果可以處理 n 筆 Request
15 | // - 且瞬間有多筆要求在等著處理
16 | // - 那這些等待中的 Request, latency 就會變很高了!
17 |
18 | //dev->SendASAP(std::move(buf)); // for low latency?
19 | //dev->SendBuffered(std::move(buf)); // for high throughput?
20 | // 由 dev 的 property 決定是否 ASAP.
21 | dev->Send(std::move(buf));
22 | }
23 | }
24 |
25 | } } // namespaces
26 |
--------------------------------------------------------------------------------
/fon9/fix/IoFixSender.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/fix/IoFixSender.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_fix_IoFixSender_hpp__
4 | #define __fon9_fix_IoFixSender_hpp__
5 | #include "fon9/fix/FixSender.hpp"
6 | #include "fon9/io/Device.hpp"
7 |
8 | namespace fon9 { namespace fix {
9 |
10 | /// \ingroup fix
11 | /// 使用 fon9::io::Device 輸出 FIX 訊息.
12 | class fon9_API IoFixSender : public FixSender {
13 | fon9_NON_COPY_NON_MOVE(IoFixSender);
14 | using base = FixSender;
15 |
16 | io::DeviceSP Device_;
17 |
18 | void OnSendFixMessage(const Locker&, BufferList buf) override;
19 |
20 | void SwapDevice(io::DeviceSP& dev) {
21 | Locker lk{this->Lock()};
22 | this->Device_.swap(dev);
23 | }
24 |
25 | public:
26 | using base::base;
27 | ~IoFixSender();
28 |
29 | void OnFixSessionDisconnected() {
30 | io::DeviceSP dev;
31 | this->SwapDevice(dev);
32 | }
33 | void OnFixSessionConnected(io::DeviceSP dev) {
34 | this->SwapDevice(dev);
35 | }
36 | io::DeviceSP GetDevice() const {
37 | return this->Device_;
38 | }
39 | };
40 | using IoFixSenderSP = intrusive_ptr;
41 |
42 | } } // namespaces
43 | #endif//__fon9_fix_IoFixSender_hpp__
44 |
--------------------------------------------------------------------------------
/fon9/fix/README.md:
--------------------------------------------------------------------------------
1 | fon9 FIX engine
2 | ===============
3 |
4 | ## 基本說明
5 | * 僅支援 FIX 4.2 及 4.4
6 |
7 | ## 基礎元件
8 | * 提供 FIX Message 的解析: `fon9::fix::FixParser`
9 | * FIX Message 打包: `fon9::fix::FixBuilder`
10 | * 將欄位直接填入輸出緩衝區, 不提供將「欄位列表」打包成 FIX Message 的功能。
11 | * `fon9::fix::FixBuilder` 填妥大部分「交易內容」相關的欄位,
12 | 其他與 FIX 協定相關的欄位(例如: CompID、BeginString), 則留給 `fon9::fix::FixSender` 處理。
13 | * 提供 Session 收送訊息記錄、狀態記錄: `fon9::fix::FixRecorder`
14 | * 取回之前送過的資料: `fon9::fix::FixRecorder::ReloadSent`
15 | * `fon9::fix::FixSender`
16 | * 完成完整的 FIX 訊息:
17 | * 填入 CompIDs
18 | * 填入 SendingTime
19 | * 填入 MsgSeqNum
20 | * 填入 MsgType
21 | * 填入 BodyLength、BeginString
22 | * 填入 CheckSum
23 | * 提供 SequenceReset
24 | * 提供 Replay
25 | * 訊息接收流程, Logon 必須是第一個訊息:
26 | * Acceptor
27 | * Device.LinkReady
28 | * Recv Logon
29 | * 檢查認證訊息
30 | * 用 Logon 提供的資訊取得 FixRecorder
31 | * 開始 FIX 訊息交換
32 | * Initiator
33 | * Device.LinkReady
34 | * 取得 FixRecorder
35 | * Send Logon
36 | * Recv Logon
37 | * 開始 FIX 訊息交換
38 | * 由於 Acceptor 必須在確認 Logon 之後才能取得正確的 FixRecorder,
39 | 所以 Logon 訊息必須由 FixSession 自行處理.
40 | * 在進入 FIX 訊息交換階段, 才將收到的訊息(包含 Logon)
41 | * 交給 `fon9::fix::FixReceiver` 去確保序號的連續.
42 | * 確定連續的訊息, 再透過 FixMsgTypeConfig.FixMsgHandler_ 接力處理.
43 |
44 |
--------------------------------------------------------------------------------
/fon9/fmkt/FmdRtsPackType.txt:
--------------------------------------------------------------------------------
1 | 2020/08/10
2 | - 在 [買賣報價、成交明細] 增加 MktSeq 欄位,在多資訊源的環境,用來過濾重複(過時)資訊:
3 | - 成交封包, 仍要提供 MktSeq, 因為試算成交的 TotalQty 為 0, 所以不能只用 TotalQty 判斷是否為舊封包.
4 |
5 | - 目前情況:
6 | 只有 Deal, BS 需要 MktSeq, 其餘現有資料都不需要 MktSeq, 在可見的未來不會有改變.
7 | f9sv_RtsPackType_DealPack,
8 | f9sv_RtsPackType_DealBS,
9 | f9sv_RtsPackType_SnapshotBS,
10 | f9sv_RtsPackType_CalculatedBS,
11 | f9sv_RtsPackType_UpdateBS,
12 |
13 | - 方法1. 在 enum f9sv_RtsPackType 增加一個 f9sv_RtsPackType_MktSeq;
14 | /// - MktSeq(Bitv) (應更新 BS.MktSeq 欄位)
15 | /// - MktSeq 之後, 接著後續的 RtsPackType 及其內容.
16 | /// - 僅在 Server 有提供 BS.MktSeq 欄位時才會有此封包.
17 | /// - 用在多資訊來源時, 判斷是否為重複資料.
18 |
19 | - 方法2. 在原本的封包增加 MktSeq(Bitv) 內容(如果有 BS.MktSeq 欄位)
20 |
21 | - 考量:
22 | - [方法1]在回補時, 會難以判斷 InfoTime?
23 | - f9sv_RtsPackType_MktSeq + InfoTime + MktSeq + [後續封包(不含InfoTime)].
24 | - [後續封包]解析要排除 InfoTime.
25 | - 依然要改動到[後續封包]解析程序?
26 | - 可將[後續封包]的InfoTime設為Null,就不會動到[後續封包]解析程序了.
27 | - [方法1]資料量會比[方法2]多 2 bytes: (PkType=f9sv_RtsPackType_MktSeq) + (MktSeq) + (後續封包:InfoTime=Null)
28 | - 會用到 MktSeq 的環境,通常API端會接收[交易所行情],用來過濾重複資訊,此時 2 bytes 是否有那麼嚴重?
29 | - 使用[方法1]的未來擴充性較佳.
30 | - 未來還有需要 MktSeq 的訊息需要擴充嗎?
31 | - 不論選擇哪種方式,打包端都必須修改。
32 | - 方法1: 解包端較單純。
33 | - 方法2: 每個提供 MktSeq 的封包都解要調整。
34 |
35 | - 最後決定: 使用[方法2.]
36 | - 依目前情況來看, 現有 enum f9sv_RtsPackType; 已確定了要修改的內容, 以後的變動不大.
37 | - 所以直接修改[打包及解包]比較單純.
38 |
--------------------------------------------------------------------------------
/fon9/fmkt/README.md:
--------------------------------------------------------------------------------
1 | fon9 financial market
2 | =====================
3 |
4 | ## 基本說明
5 | * 金融市場擴充模組
6 | * 基本行情
7 | * 下單基底: Server/Client 共用的部分
8 |
9 | ## 基礎元件
10 | * Symb、SymbTree
11 |
12 | ## 基本行情
13 | * SymbRef、SymbBS、SymbDeal
14 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbBS.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbBS.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbBS_hpp__
4 | #define __fon9_fmkt_SymbBS_hpp__
5 | #include "fon9/fmkt/SymbDy.hpp"
6 | #include "fon9/fmkt/SymbBSData.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | /// \ingroup fmkt
11 | /// 商品資料的擴充: 行情的買賣報價.
12 | fon9_API_TEMPLATE_CLASS(SymbTwsBS, SimpleSymbData, SymbTwsBSData);
13 | fon9_API_TEMPLATE_CLASS(SymbTwfBS, SimpleSymbData, SymbTwfBSData);
14 |
15 | /// 不包含「衍生買賣」, 包含 LmtFlags.
16 | fon9_API seed::Fields SymbTwsBS_MakeFields(bool isAddMarketSeq);
17 | /// 包含「衍生買賣」, 不包含 LmtFlags.
18 | fon9_API seed::Fields SymbTwfBS_MakeFields(bool isAddMarketSeq, bool isAddChannelSeq);
19 |
20 | using SymbTwaBS = SymbTwfBS;
21 | fon9_API seed::Fields SymbTwaBS_MakeFields(bool isAddMarketSeq);
22 |
23 | class fon9_API SymbBSTabDy : public SymbDataTab {
24 | fon9_NON_COPY_NON_MOVE(SymbBSTabDy);
25 | using base = SymbDataTab;
26 | public:
27 | SymbBSTabDy(Named&& named, bool isAddMarketSeq = true)
28 | : base{std::move(named), SymbTwaBS_MakeFields(isAddMarketSeq), seed::TabFlag::NoSapling_NoSeedCommand_Writable} {
29 | }
30 |
31 | SymbDataSP FetchSymbData(Symb&) override;
32 | };
33 |
34 | } } // namespaces
35 | #endif//__fon9_fmkt_SymbBS_hpp__
36 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbBreakSt.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbBreakSt.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbBreakSt.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | seed::Fields SymbBreakSt_MakeFieldsTws() {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbBreakSt, Data_.BreakHHMMSS_, "BreakTime"));
11 | flds.Add(fon9_MakeField(SymbBreakSt, Data_.RestartHHMMSS_, "RestartTime"));
12 | return flds;
13 | }
14 |
15 | seed::Fields SymbBreakSt_MakeFieldsTwf() {
16 | seed::Fields flds = SymbBreakSt_MakeFieldsTws();
17 | flds.Add(fon9_MakeField(SymbBreakSt, Data_.ReopenHHMMSS_, "ReopenTime"));
18 | flds.Add(fon9_MakeField(SymbBreakSt, Data_.Reason_, "Reason"));
19 | return flds;
20 | }
21 |
22 | } } // namespaces
23 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbDy.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbDy.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbDy.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | SymbDy::SymbDy(SymbDyTreeSP symbTreeSP, const StrView& symbid) : base{symbid}, SymbTreeSP_{std::move(symbTreeSP)} {
8 | }
9 | SymbData* SymbDy::GetSymbData(int tabid) {
10 | if (tabid <= 0)
11 | return this;
12 | ExDatas::Locker lk{this->ExDatas_};
13 | return (static_cast(tabid) <= lk->size() ? (*lk)[static_cast(tabid - 1)].get() : nullptr);
14 | }
15 | SymbData* SymbDy::FetchSymbData(int tabid) {
16 | if (tabid <= 0)
17 | return this;
18 | SymbDataTab* tab = dynamic_cast(this->SymbTreeSP_->LayoutSP_->GetTab(static_cast(tabid)));
19 | if (tab == nullptr)
20 | return nullptr;
21 | ExDatas::Locker lk{this->ExDatas_};
22 | if (lk->size() < static_cast(tabid))
23 | lk->resize(static_cast(tabid));
24 | if (SymbData* dat = (*lk)[static_cast(tabid - 1)].get())
25 | return dat;
26 | return ((*lk)[static_cast(tabid - 1)] = tab->FetchSymbData(*this)).get();
27 | }
28 |
29 | //--------------------------------------------------------------------------//
30 |
31 | SymbSP SymbDyTree::MakeSymb(const StrView& symbid) {
32 | return SymbSP{new SymbDy(this, symbid)};
33 | }
34 |
35 | } } // namespaces
36 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbDynBand.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbDynBand.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbDynBand.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | seed::Fields SymbDynBand_MakeFields() {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbDynBand, Data_.DynBandSt_, "St"));
11 | flds.Add(fon9_MakeField(SymbDynBand, Data_.StHHMMSS_, "Time"));
12 | flds.Add(fon9_MakeField(SymbDynBand, Data_.Reason_, "Reason"));
13 | flds.Add(fon9_MakeField(SymbDynBand, Data_.SideType_, "SideType"));
14 | flds.Add(fon9_MakeField(SymbDynBand, Data_.RangeL_, "RangeL"));
15 | flds.Add(fon9_MakeField(SymbDynBand, Data_.RangeS_, "RangeS"));
16 | return flds;
17 | }
18 |
19 | } } // namespaces
20 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbFuoClosing.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbFuoClosing.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbFuoClosing.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | fon9_API seed::Fields SymbFuoClosing_MakeFields() {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbFuoClosing, Data_.PriSettlement_, "PriSettlement"));
11 | return flds;
12 | }
13 |
14 | } } // namespaces
15 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbFuoClosing.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbFuoClosing.hpp
2 | //
3 | // 期權商品收盤後相關資訊, 例如: 結算價;
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __fon9_fmkt_SymbFuoClosing_hpp__
7 | #define __fon9_fmkt_SymbFuoClosing_hpp__
8 | #include "fon9/fmkt/Symb.hpp"
9 | #include "fon9/fmkt/FmktTypes.hpp"
10 |
11 | namespace fon9 { namespace fmkt {
12 |
13 | struct SymbFuoClosing_Data {
14 | /// 結算價
15 | Pri PriSettlement_{Pri::Null()};
16 |
17 | void Clear() {
18 | this->PriSettlement_.AssignNull();
19 | }
20 | bool operator==(const SymbFuoClosing_Data& rhs) const {
21 | return this->PriSettlement_ == rhs.PriSettlement_;
22 | }
23 | bool operator!=(const SymbFuoClosing_Data& rhs) const {
24 | return !this->operator==(rhs);
25 | }
26 | };
27 |
28 | /// \ingroup fmkt
29 | /// 商品資料的擴充: 期權商品收盤後相關資訊.
30 | fon9_API_TEMPLATE_CLASS(SymbFuoClosing, SimpleSymbData, SymbFuoClosing_Data);
31 |
32 | fon9_API seed::Fields SymbFuoClosing_MakeFields();
33 |
34 | } } // namespaces
35 | #endif//__fon9_fmkt_SymbFuoClosing_hpp__
36 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbQuoteReq.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbQuoteReq.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbQuoteReq.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | seed::Fields SymbQuoteReq_MakeFields() {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbQuoteReq, Data_.DisclosureTime_, "Time"));
11 | flds.Add(fon9_MakeField(SymbQuoteReq, Data_.DurationSeconds_, "DurSecs"));
12 | return flds;
13 | }
14 |
15 | } } // namespaces
16 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbQuoteReq.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbQuoteReq.hpp
2 | //
3 | // 商品詢價要求 相關欄位.
4 | //
5 | // \author fonwinz@gmail.com
6 | #ifndef __fon9_fmkt_SymbQuoteReq_hpp__
7 | #define __fon9_fmkt_SymbQuoteReq_hpp__
8 | #include "fon9/fmkt/Symb.hpp"
9 | #include "fon9/TimeInterval.hpp"
10 |
11 | namespace fon9 { namespace fmkt {
12 |
13 | struct SymbQuoteReq_Data {
14 | /// 詢價揭示時間.
15 | DayTime DisclosureTime_{DayTime::Null()};
16 | /// 詢價持續時間.
17 | uint16_t DurationSeconds_{};
18 | char Padding___[6];
19 |
20 | void Clear() {
21 | this->DisclosureTime_.AssignNull();
22 | this->DurationSeconds_ = 0;
23 | }
24 | bool operator==(const SymbQuoteReq_Data& rhs) const {
25 | return this->DisclosureTime_ == rhs.DisclosureTime_
26 | && this->DurationSeconds_ == rhs.DurationSeconds_;
27 | }
28 | bool operator!=(const SymbQuoteReq_Data& rhs) const {
29 | return !this->operator==(rhs);
30 | }
31 | };
32 |
33 | /// \ingroup fmkt
34 | /// 商品資料的擴充: 詢價要求.
35 | fon9_API_TEMPLATE_CLASS(SymbQuoteReq, SimpleSymbData, SymbQuoteReq_Data);
36 |
37 | fon9_API seed::Fields SymbQuoteReq_MakeFields();
38 |
39 | } } // namespaces
40 | #endif//__fon9_fmkt_SymbQuoteReq_hpp__
41 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbRef.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbRef.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbRef.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | seed::Fields SymbRef_MakeFields() {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbRef, Data_.PriRef_, "PriRef"));
11 | flds.Add(fon9_MakeField(SymbRef, Data_.PriUpLmt_, "PriUpLmt"));
12 | flds.Add(fon9_MakeField(SymbRef, Data_.PriDnLmt_, "PriDnLmt"));
13 | return flds;
14 | }
15 |
16 | SymbRefTabDy::SymbDataSP SymbRefTabDy::FetchSymbData(Symb&) {
17 | return SymbDataSP{new SymbRef{}};
18 | }
19 |
20 | } } // namespaces
21 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbRef.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbRef.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbRef_hpp__
4 | #define __fon9_fmkt_SymbRef_hpp__
5 | #include "fon9/fmkt/SymbDy.hpp"
6 | #include "fon9/fmkt/FmktTypes.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | struct SymbRef_Data {
11 | Pri PriRef_{};
12 | Pri PriUpLmt_{};
13 | Pri PriDnLmt_{};
14 |
15 | void Clear() {
16 | ForceZeroNonTrivial(this);
17 | }
18 | bool operator==(const SymbRef_Data& rhs) const {
19 | return memcmp(this, &rhs, sizeof(*this)) == 0;
20 | }
21 | bool operator!=(const SymbRef_Data& rhs) const {
22 | return !this->operator==(rhs);
23 | }
24 | };
25 |
26 | /// \ingroup fmkt
27 | /// 商品資料的擴充: 參考價.
28 | fon9_API_TEMPLATE_CLASS(SymbRef, SimpleSymbData, SymbRef_Data);
29 |
30 | fon9_API seed::Fields SymbRef_MakeFields();
31 |
32 | class fon9_API SymbRefTabDy : public SymbDataTab {
33 | fon9_NON_COPY_NON_MOVE(SymbRefTabDy);
34 | using base = SymbDataTab;
35 | public:
36 | SymbRefTabDy(Named&& named)
37 | : base{std::move(named), SymbRef_MakeFields(), seed::TabFlag::NoSapling_NoSeedCommand_Writable} {
38 | }
39 |
40 | SymbDataSP FetchSymbData(Symb&) override;
41 | };
42 |
43 | } } // namespaces
44 | #endif//__fon9_fmkt_SymbRef_hpp__
45 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTabNames.h:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTabNames.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbTabNames_h__
4 | #define __fon9_fmkt_SymbTabNames_h__
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #define fon9_kCSTR_TabName_Base "Base"
11 | #define fon9_kCSTR_TabName_Ref "Ref"
12 | #define fon9_kCSTR_TabName_BS "BS"
13 | #define fon9_kCSTR_TabName_Deal "Deal"
14 | #define fon9_kCSTR_TabName_Open "Open"
15 | #define fon9_kCSTR_TabName_High "High"
16 | #define fon9_kCSTR_TabName_Low "Low"
17 | #define fon9_kCSTR_TabName_BreakSt "BreakSt"
18 | #define fon9_kCSTR_TabName_Closing "Closing"
19 | #define fon9_kCSTR_TabName_DynBand "DynBand"
20 | #define fon9_kCSTR_TabName_QuoteReq "QuoteReq"
21 | #define fon9_kCSTR_TabName_Rt "Rt"
22 |
23 | #ifdef __cplusplus
24 | }
25 | #endif
26 | #endif//__fon9_fmkt_SymbTabNames_h__
27 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTimePri.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbHL.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTimePri.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | seed::Fields SymbTimePri_MakeFields(std::string priName) {
9 | seed::Fields flds;
10 | flds.Add(fon9_MakeField(SymbTimePri, Data_.Time_, "Time"));
11 | flds.Add(fon9_MakeField(SymbTimePri, Data_.Pri_, std::move(priName)));
12 | return flds;
13 | }
14 |
15 | } } // namespaces
16 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwa.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwa.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTwa.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | SymbTwa::~SymbTwa() {
8 | }
9 | bool SymbTwa::IsExpired(unsigned tdayYYYYMMDD) const {
10 | return IsSymbExpired(this->EndYYYYMMDD_, tdayYYYYMMDD);
11 | }
12 | void SymbTwa::SessionClear(SymbTree& owner, f9fmkt_TradingSessionId tsesId) {
13 | if (this->TradingMarket_ == f9fmkt_TradingMarket_TwFUT
14 | || this->TradingMarket_ == f9fmkt_TradingMarket_TwOPT)
15 | base::SessionClear(owner, tsesId);
16 | else {
17 | this->TradingSessionId_ = tsesId;
18 | this->TradingSessionSt_ = f9fmkt_TradingSessionSt_Clear;
19 | this->SymbTwaBaseSessionClear();
20 | }
21 | }
22 | void SymbTwa::OnSymbDailyClear(SymbTree& tree, const Symb& symb) {
23 | base::OnSymbDailyClear(tree, symb);
24 | this->SymbTwaBaseDailyClear();
25 | }
26 | void SymbTwa::OnSymbSessionClear(SymbTree& tree, const Symb& symb) {
27 | base::OnSymbSessionClear(tree, symb);
28 | this->SymbTwaBaseSessionClear();
29 | }
30 | seed::Fields SymbTwa::MakeFields() {
31 | seed::Fields flds = base::MakeFields();
32 | SymbTwaBase::AddFields(flds);
33 | return flds;
34 | }
35 |
36 | } } // namespaces
37 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwa.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwa.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbTwa_hpp__
4 | #define __fon9_fmkt_SymbTwa_hpp__
5 | #include "fon9/fmkt/SymbTwaBase.hpp"
6 | #include "fon9/fmkt/Symb.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | /// \ingroup fmkt
11 | /// 台灣 「證券」+「期交所」預設的商品基本類別.
12 | /// - Symb + SymbTwaBase
13 | class fon9_API SymbTwa : public Symb, public SymbTwaBase {
14 | fon9_NON_COPY_NON_MOVE(SymbTwa);
15 | using base = Symb;
16 |
17 | public:
18 | using base::base;
19 | ~SymbTwa();
20 |
21 | /// 使用 this->EndYYYYMMDD_ 及 this->TDayYYYYMMDD_ 判斷是否過期.
22 | bool IsExpired() const {
23 | return this->IsSymbExpired(this->EndYYYYMMDD_, this->TDayYYYYMMDD_);
24 | }
25 | bool IsExpired(unsigned tdayYYYYMMDD) const override;
26 | void OnSymbDailyClear(SymbTree& tree, const Symb& symb) override;
27 | void OnSymbSessionClear(SymbTree& tree, const Symb& symb) override;
28 | /// 台灣證券的換盤, 不應清除 SymbData(Open/High/Low...);
29 | /// 台灣期權的換盤, 需要清除 SymbData(Open/High/Low...);
30 | void SessionClear(SymbTree& owner, f9fmkt_TradingSessionId tsesId) override;
31 |
32 | static seed::Fields MakeFields();
33 | };
34 | using SymbTwaSP = intrusive_ptr;
35 |
36 | } } // namespaces
37 | #endif//__fon9_fmkt_SymbTwa_hpp__
38 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwaBase.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwaBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTwaBase.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | } } // namespaces
8 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwaBase.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwaBase.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbTwaBase_hpp__
4 | #define __fon9_fmkt_SymbTwaBase_hpp__
5 | #include "fon9/fmkt/SymbTwsBase.hpp"
6 | #include "fon9/fmkt/SymbTwfBase.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | /// \ingroup fmkt
11 | /// 台灣 「證券」+「期交所」預設的商品基本資料.
12 | struct SymbTwaBase : public SymbTwsBase, public SymbTwfBase {
13 | template
14 | static void AddFields(seed::Fields& flds) {
15 | SymbTwsBase::AddFields(flds);
16 | SymbTwfBase::AddFields(flds);
17 | }
18 |
19 | void SymbTwaBaseDailyClear() {
20 | this->SymbTwsBaseDailyClear();
21 | this->SymbTwfBaseDailyClear();
22 | }
23 | void SymbTwaBaseSessionClear() {
24 | this->SymbTwsBaseSessionClear();
25 | this->SymbTwfBaseSessionClear();
26 | }
27 | };
28 |
29 | } } // namespaces
30 | #endif//__fon9_fmkt_SymbTwaBase_hpp__
31 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwf.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwf.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTwf.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | SymbTwf::~SymbTwf() {
8 | }
9 | bool SymbTwf::IsExpired(unsigned tdayYYYYMMDD) const {
10 | return IsSymbExpired(this->EndYYYYMMDD_, tdayYYYYMMDD);
11 | }
12 | void SymbTwf::OnSymbDailyClear(SymbTree& tree, const Symb& symb) {
13 | base::OnSymbDailyClear(tree, symb);
14 | this->SymbTwfBaseDailyClear();
15 | }
16 | void SymbTwf::OnSymbSessionClear(SymbTree& tree, const Symb& symb) {
17 | base::OnSymbSessionClear(tree, symb);
18 | this->SymbTwfBaseSessionClear();
19 | }
20 | seed::Fields SymbTwf::MakeFields() {
21 | seed::Fields flds = base::MakeFields();
22 | SymbTwfBase::AddFields(flds);
23 | return flds;
24 | }
25 |
26 | } } // namespaces
27 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwf.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwf.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbTwf_hpp__
4 | #define __fon9_fmkt_SymbTwf_hpp__
5 | #include "fon9/fmkt/SymbTwfBase.hpp"
6 | #include "fon9/fmkt/Symb.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | /// \ingroup fmkt
11 | /// 台灣期交所預設的基本商品類別.
12 | /// - Symb + SymbTwfBase
13 | class fon9_API SymbTwf : public Symb, public SymbTwfBase {
14 | fon9_NON_COPY_NON_MOVE(SymbTwf);
15 | using base = Symb;
16 |
17 | public:
18 | using base::base;
19 | ~SymbTwf();
20 |
21 | bool IsExpired(unsigned tdayYYYYMMDD) const override;
22 | void OnSymbDailyClear(SymbTree& tree, const Symb& symb) override;
23 | void OnSymbSessionClear(SymbTree& tree, const Symb& symb) override;
24 |
25 | /// base::MakeFields(); and:
26 | /// - FlowGroup, PriceOrigDiv, StrikePriceDiv, ExgSymbSeq
27 | /// - EndDate
28 | static seed::Fields MakeFields();
29 | };
30 | using SymbTwfSP = intrusive_ptr;
31 |
32 | } } // namespaces
33 | #endif//__fon9_fmkt_SymbTwf_hpp__
34 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwfBase.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwfBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTwfBase.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | void SymbTwfBase::AddFields(int ofsadj, seed::Fields& flds) {
9 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, FlowGroup));
10 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, PriceOrigDiv));
11 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, StrikePriceDiv));
12 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, ExgSymbSeq));
13 | flds.Add(fon9_MakeField_OfsAdj (ofsadj, SymbTwfBase, EndYYYYMMDD_, "EndDate"));
14 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, SettleYYYYMM));
15 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, StrikePrice));
16 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwfBase, CallPut));
17 | }
18 |
19 | } } // namespaces
20 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTws.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTws.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTws.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | SymbTws::~SymbTws() {
8 | }
9 | void SymbTws::OnSymbDailyClear(SymbTree& tree, const Symb& symb) {
10 | base::OnSymbDailyClear(tree, symb);
11 | this->SymbTwsBaseDailyClear();
12 | }
13 | void SymbTws::SessionClear(SymbTree& owner, f9fmkt_TradingSessionId tsesId) {
14 | (void)owner;
15 | this->TradingSessionId_ = tsesId;
16 | this->TradingSessionSt_ = f9fmkt_TradingSessionSt_Clear;
17 | this->SymbTwsBaseSessionClear();
18 | }
19 | seed::Fields SymbTws::MakeFields() {
20 | seed::Fields flds = base::MakeFields();
21 | SymbTwsBase::AddFields(flds);
22 | return flds;
23 | }
24 |
25 | } } // namespaces
26 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTws.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTws.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_SymbTws_hpp__
4 | #define __fon9_fmkt_SymbTws_hpp__
5 | #include "fon9/fmkt/SymbTwsBase.hpp"
6 | #include "fon9/fmkt/Symb.hpp"
7 |
8 | namespace fon9 { namespace fmkt {
9 |
10 | /// \ingroup fmkt
11 | /// 台灣證券預設的基本商品類別.
12 | /// - Symb + SymbTwsBase
13 | class fon9_API SymbTws : public Symb, public SymbTwsBase {
14 | fon9_NON_COPY_NON_MOVE(SymbTws);
15 | using base = Symb;
16 |
17 | public:
18 | using base::base;
19 | ~SymbTws();
20 |
21 | void OnSymbDailyClear(SymbTree& tree, const Symb& symb) override;
22 | /// 台灣證券的換盤, 不應清除 SymbData(Open/High/Low...);
23 | /// - 設定 this->TradingSessionId_ = tsesId;
24 | /// - 設定 this->TradingSessionSt_ = f9fmkt_TradingSessionSt_Clear;
25 | /// - 不會觸發 this->GetSymbData(tabid=0..N)->OnSymbSessionClear();
26 | void SessionClear(SymbTree& owner, f9fmkt_TradingSessionId tsesId) override;
27 |
28 | /// base::MakeFields(); and:
29 | /// - ShUnit
30 | /// - TwsFlags
31 | static seed::Fields MakeFields();
32 | };
33 | using SymbTwsSP = intrusive_ptr;
34 |
35 | } } // namespaces
36 | #endif//__fon9_fmkt_SymbTws_hpp__
37 |
--------------------------------------------------------------------------------
/fon9/fmkt/SymbTwsBase.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/fmkt/SymbTwsBase.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/fmkt/SymbTwsBase.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | void SymbTwsBase::AddFields(int ofsadj, seed::Fields& flds) {
9 | flds.Add(fon9_MakeField2_OfsAdj(ofsadj, SymbTwsBase, ShUnit));
10 | flds.Add(seed::FieldSP{new seed::FieldIntHx>(
11 | Named("TwsFlags"), ofsadj + fon9_OffsetOfRawPointer(SymbTwsBase, TwsFlags_))});
12 | }
13 |
14 | } } // namespaces
15 |
--------------------------------------------------------------------------------
/fon9/fmkt/TradingLineGroup.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/fmkt/TradingLineGroup.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/fmkt/TradingLineGroup.hpp"
4 |
5 | namespace fon9 { namespace fmkt {
6 |
7 | TradingLgMgrBase::~TradingLgMgrBase() {
8 | }
9 | TradingLgMgrBase::LgItemBaseSP TradingLgMgrBase::MakeLgItem(StrView tag, StrView cfgln) {
10 | if (tag.size() != fon9_kSIZE_LgTAG_LEAD + 1)
11 | return nullptr;
12 | const char* ptag = tag.begin();
13 | // Unknown tag.
14 | if (memcmp(ptag, fon9_kCSTR_LgTAG_LEAD, fon9_kSIZE_LgTAG_LEAD) != 0)
15 | return nullptr;
16 | const LgOut lgId = static_cast(ptag[fon9_kSIZE_LgTAG_LEAD]);
17 | // Unknown LgId.
18 | if (!IsValidateLgOut(lgId))
19 | return nullptr;
20 | const uint8_t lgIdx = LgOutToIndex(lgId);
21 | // Dup Lg.
22 | if (this->LgItems_[lgIdx].get() != nullptr)
23 | return nullptr;
24 | StrView title = SbrFetchNoTrim(cfgln, ',');
25 | LgItemBaseSP retval = this->CreateLgItem(Named(
26 | tag.ToString(),
27 | StrView_ToNormalizeStr(StrTrimRemoveQuotes(title)),
28 | StrView_ToNormalizeStr(StrTrimRemoveQuotes(cfgln))
29 | ));
30 | this->LgItems_[lgIdx] = retval;
31 | this->Sapling_->Add(retval);
32 | return retval;
33 | }
34 |
35 | } } // namespaces
36 |
--------------------------------------------------------------------------------
/fon9/fmkt/TradingLineManagerSeed.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/fmkt/TradingLineManagerSeed.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/fmkt/TradingLineManagerSeed.hpp"
4 | #include "fon9/fmkt/TradingLine.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | TradingLineManagerSeed::~TradingLineManagerSeed() {
9 | }
10 | void TradingLineManagerSeed::OnSeedCommand(seed::SeedOpResult& res, StrView cmdln, seed::FnCommandResultHandler resHandler,
11 | seed::MaTreeBase::Locker&& ulk, seed::SeedVisitor* visitor) {
12 | if (cmdln == "?") {
13 | res.OpResult_ = seed::OpResult::no_error;
14 | resHandler(res,
15 | //"xx" fon9_kCSTR_CELLSPL "需要輸入參數的指令" fon9_kCSTR_CELLSPL "輸入參數的提示字串." fon9_kCSTR_ROWSPL
16 | "st" fon9_kCSTR_CELLSPL "State info"
17 | );
18 | return;
19 | }
20 | if (iequals(cmdln, "st")) {
21 | if (auto* lmgr = dynamic_cast(this->Sapling_.get())) {
22 | fon9::RevBufferList rbuf{256};
23 | lmgr->Lock()->GetStInfo(rbuf);
24 | resHandler(res, ToStrView(BufferTo(rbuf.MoveOut())));
25 | return;
26 | }
27 | }
28 | base::OnSeedCommand(res, cmdln, std::move(resHandler), std::move(ulk), visitor);
29 | }
30 |
31 | } } // namespaces
32 |
--------------------------------------------------------------------------------
/fon9/fmkt/TradingLineManagerSeed.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/fmkt/TradingLineManagerSeed.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_fmkt_TradingLineManagerSeed_hpp__
4 | #define __fon9_fmkt_TradingLineManagerSeed_hpp__
5 | #include "fon9/seed/MaTree.hpp"
6 |
7 | namespace fon9 { namespace fmkt {
8 |
9 | class fon9_API TradingLineManagerSeed : public seed::NamedSapling {
10 | fon9_NON_COPY_NON_MOVE(TradingLineManagerSeed);
11 | using base = seed::NamedSapling;
12 | public:
13 | using base::base;
14 | ~TradingLineManagerSeed();
15 | /// 提供現在的 [線路 & Helper] 狀態
16 | void OnSeedCommand(seed::SeedOpResult& res, StrView cmdln, seed::FnCommandResultHandler resHandler,
17 | seed::MaTreeBase::Locker&& ulk, seed::SeedVisitor* visitor) override;
18 | };
19 |
20 |
21 | } } // namespaces
22 | #endif//__fon9_fmkt_TradingLineManagerSeed_hpp__
23 |
--------------------------------------------------------------------------------
/fon9/fmkt/TradingRequest.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/fmkt/TradingRequest.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/fmkt/TradingRequest.hpp"
4 | #include "fon9/fmkt/TradingLine.hpp"
5 |
6 | namespace fon9 { namespace fmkt {
7 |
8 | TradingRxItem::~TradingRxItem() {
9 | }
10 | void TradingRxItem::FreeThis() {
11 | delete this;
12 | }
13 | void TradingRxItem::RevPrint(RevBuffer&) const {
14 | }
15 | const TradingRxItem* TradingRxItem::CastToRequest() const {
16 | return nullptr;
17 | }
18 | const TradingRxItem* TradingRxItem::CastToOrder() const {
19 | return nullptr;
20 | }
21 | const TradingRxItem* TradingRxItem::CastToEvent() const {
22 | return nullptr;
23 | }
24 | //--------------------------------------------------------------------------//
25 | TradingRequest::~TradingRequest() {
26 | }
27 | bool TradingRequest::PreOpQueuingRequest(TradingLineManager& from) const {
28 | (void)from;
29 | return false;
30 | }
31 | TradingRequest::OpQueuingRequestResult TradingRequest::OpQueuingRequest(TradingLineManager& from,
32 | TradingRequest& queuingRequest) {
33 | (void)from; (void)queuingRequest;
34 | return Op_NotSupported;
35 | }
36 | bool TradingRequest::IsPreferTradingLine(TradingLine& tline) const {
37 | return tline.IsOrigSender(*this);
38 | }
39 |
40 | } } // namespaces
41 |
--------------------------------------------------------------------------------
/fon9/framework/Fon9Co_main.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/framework/Fon9Co_main.cpp
2 | // fon9 console: 直接轉呼叫 fon9::Fon9CoRun();
3 | // \author fonwinz@gmail.com
4 | #include "fon9/framework/Framework.hpp"
5 |
6 | int main(int argc, const char* argv[]) {
7 | return fon9::Fon9CoRun(argc, argv, nullptr);
8 | }
9 |
--------------------------------------------------------------------------------
/fon9/framework/FrameworkFlag.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/framework/FrameworkFlag.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/framework/FrameworkFlag.hpp"
4 |
5 | namespace fon9 {
6 |
7 | fon9_API bool IsFrameworkInitializing = false;
8 |
9 | } // namespaces
10 |
--------------------------------------------------------------------------------
/fon9/framework/FrameworkFlag.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/framework/FrameworkFlag.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_framework_FrameworkFlag_hpp__
4 | #define __fon9_framework_FrameworkFlag_hpp__
5 | #include "fon9/sys/Config.hpp"
6 |
7 | namespace fon9 {
8 |
9 | /// 預設為 false,
10 | /// - 當 Framework::Initialize() 開始執行時設為 true;
11 | /// - 在 Framework::Start() 返回前設為 false;
12 | /// - 在有需要 MaAuth 的環境下(例: MaIo), 啟動前應判斷此旗標.
13 | extern fon9_API bool IsFrameworkInitializing;
14 |
15 | } // namespaces
16 | #endif//__fon9_framework_FrameworkFlag_hpp__
17 |
--------------------------------------------------------------------------------
/fon9/framework/NamedIoManager.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/framework/NamedIoManager.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/framework/IoManagerTree.hpp"
4 | #include "fon9/seed/SysEnv.hpp"
5 | #include "fon9/seed/Plugins.hpp"
6 |
7 | namespace fon9 {
8 |
9 | static bool NamedIoManager_Start(seed::PluginsHolder& holder, StrView args) {
10 | IoManagerArgs iomArgs;
11 | StrView tag, value;
12 | while (fon9::SbrFetchTagValue(args, tag, value)) {
13 | iomArgs.SetTagValue(holder, tag, value);
14 | }
15 | if (!iomArgs.Name_.empty() && IoManagerTree::Plant(*holder.Root_, iomArgs))
16 | return true;
17 | holder.SetPluginsSt(fon9::LogLevel::Error, "Name=", iomArgs.Name_, "|err='Name' is dup or empty");
18 | return false;
19 | }
20 |
21 | } // namespaces
22 |
23 | extern "C" fon9_API fon9::seed::PluginsDesc f9p_NamedIoManager;
24 | static fon9::seed::PluginsPark f9pAutoPluginsReg{"NamedIoManager", &f9p_NamedIoManager};
25 |
26 | fon9::seed::PluginsDesc f9p_NamedIoManager{
27 | "",
28 | &fon9::NamedIoManager_Start,
29 | nullptr,
30 | nullptr,
31 | };
32 |
--------------------------------------------------------------------------------
/fon9/framework/SessionFactoryConfigWithAuthMgr.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/framework/SessionFactoryConfigWithAuthMgr.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/framework/SessionFactoryConfigWithAuthMgr.hpp"
4 |
5 | namespace fon9 {
6 |
7 | bool SessionFactoryConfigWithAuthMgr::OnUnknownTag(seed::PluginsHolder& holder, StrView tag, StrView value) {
8 | if (tag == "AuthMgr") {
9 | this->AuthMgrName_ = value;
10 | return true;
11 | }
12 | return base::OnUnknownTag(holder, tag, value);
13 | }
14 | auth::AuthMgrSP SessionFactoryConfig_GetAuthMgr(IoFactoryConfigParser& parser,
15 | seed::MaTree& root,
16 | const StrView& authMgrName) {
17 | if (auto authMgr = root.Get(authMgrName))
18 | return authMgr;
19 | parser.ErrMsg_ += "|err=Unknown AuthMgr";
20 | if (!authMgrName.empty()) {
21 | parser.ErrMsg_.push_back('=');
22 | authMgrName.AppendTo(parser.ErrMsg_);
23 | }
24 | return nullptr;
25 | }
26 |
27 | } // namespaces
28 |
--------------------------------------------------------------------------------
/fon9/intrusive_ref_counter.hpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fonwin/libfon9/c07ca2ffb3547a03a31c41db5ad036ab6ee859bc/fon9/intrusive_ref_counter.hpp
--------------------------------------------------------------------------------
/fon9/io/FdrDgram.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrDgram.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/sys/Config.h"
4 | #ifdef fon9_POSIX
5 | #include "fon9/io/FdrDgram.hpp"
6 |
7 | namespace fon9 { namespace io {
8 |
9 | bool FdrDgramImpl::OpImpl_ConnectTo(const SocketAddress& addr, SocketResult& soRes) {
10 | this->State_ = State::Connecting;
11 | if (!addr.IsEmpty()) {
12 | // connect(remote address) for send: writev() 的對方位置.
13 | if (::connect(this->GetFD(), &addr.Addr_, addr.GetAddrLen()) != 0) {
14 | soRes = SocketResult{"connect"};
15 | return false;
16 | }
17 | }
18 | this->State_ = State::Connected;
19 | this->Owner_->OpImpl_Connected(this->GetFD());
20 | return true;
21 | }
22 |
23 | void FdrDgramImpl::OnFdrEvent_Handling(FdrEventFlag evs) {
24 | FdrEventProcessor(this, *this->Owner_, evs);
25 | }
26 | void FdrDgramImpl::OnFdrEvent_StartSend() {
27 | this->StartSend(*this->Owner_);
28 | }
29 | void FdrDgramImpl::OnFdrSocket_Error(std::string errmsg) {
30 | this->Owner_->OnSocketError(this, std::move(errmsg));
31 | }
32 | void FdrDgramImpl::SocketError(StrView fnName, int eno) {
33 | switch (eno) {
34 | case ECONNREFUSED: /* 111:Connection refused */
35 | // 若對方(如果對方為本機ip)沒有 listen udp port, 則在 writev() 時會有此錯誤!
36 | return;
37 | }
38 | base::SocketError(fnName, eno);
39 | }
40 |
41 | } } // namespaces
42 | #endif
43 |
--------------------------------------------------------------------------------
/fon9/io/FdrDgram.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrDgram.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_io_FdrDgram_hpp__
4 | #define __fon9_io_FdrDgram_hpp__
5 | #include "fon9/io/DgramBase.hpp"
6 | #include "fon9/io/FdrSocketClient.hpp"
7 |
8 | namespace fon9 { namespace io {
9 |
10 | struct FdrDgramImpl : public FdrSocketClientImpl {
11 | fon9_NON_COPY_NON_MOVE(FdrDgramImpl);
12 | using base = FdrSocketClientImpl;
13 | virtual void OnFdrEvent_Handling(FdrEventFlag evs) override;
14 | virtual void OnFdrEvent_StartSend() override;
15 | virtual void OnFdrSocket_Error(std::string errmsg) override;
16 | virtual void SocketError(StrView fnName, int eno) override;
17 |
18 | public:
19 | using OwnerDevice = DgramT;
20 | using OwnerDeviceSP = intrusive_ptr;
21 | const OwnerDeviceSP Owner_;
22 |
23 | FdrDgramImpl(OwnerDevice* owner, Socket&& so, SocketResult&)
24 | : base{*owner->IoService_, std::move(so)}
25 | , Owner_{owner} {
26 | }
27 | bool OpImpl_ConnectTo(const SocketAddress& addr, SocketResult& soRes);
28 | };
29 |
30 | //--------------------------------------------------------------------------//
31 |
32 | /// \ingroup io
33 | /// 使用 fd 的實作的 Dgram.
34 | using FdrDgram = DeviceImpl_DeviceStartSend;
35 |
36 | } } // namespaces
37 | #endif//__fon9_io_FdrDgram_hpp__
38 |
--------------------------------------------------------------------------------
/fon9/io/FdrServiceEpoll.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrServiceEpoll.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_io_FdrServiceEpoll_hpp__
4 | #define __fon9_io_FdrServiceEpoll_hpp__
5 | #ifdef __linux__
6 | #include "fon9/io/FdrService.hpp"
7 | #include "fon9/ObjPool.hpp"
8 |
9 | namespace fon9 { namespace io {
10 |
11 | struct FdrServiceEpoll {
12 | using MakeResult = Result2;
13 | static FdrServiceSP MakeService(const IoServiceArgs& ioArgs, const std::string& thrName, MakeResult& err);
14 | };
15 |
16 | /// \ingroup io
17 | /// 提供使用 epoll 處理 non-blocking fd 讀寫事件服務.
18 | class FdrThreadEpoll : public FdrThread {
19 | const FdrAuto FdrEpoll_;
20 | struct EvHandler : public FdrEventHandlerSP {
21 | using FdrEventHandlerSP::FdrEventHandlerSP;
22 | FdrEventFlag Events_{FdrEventFlag::None};
23 | };
24 | using EvHandlers = ObjPool;
25 |
26 | void ProcessPendings(Fdr::fdr_t epFdr, EvHandlers& evHandlers);
27 | virtual void ThrRunImpl(const ServiceThreadArgs& args) override;
28 |
29 | public:
30 | FdrThreadEpoll(FdrServiceEpoll::MakeResult& res);
31 |
32 | virtual ~FdrThreadEpoll();
33 | };
34 |
35 | } } // namespaces
36 | #endif//__linux__
37 | #endif//__fon9_io_FdrServiceEpoll_hpp__
38 |
--------------------------------------------------------------------------------
/fon9/io/FdrSocketClient.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrSocketClient.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/sys/Config.h"
4 | #ifdef fon9_POSIX
5 | #include "fon9/io/FdrSocketClient.hpp"
6 |
7 | namespace fon9 { namespace io {
8 |
9 | void FdrSocketClientImpl::OnFdrEvent_AddRef() {
10 | intrusive_ptr_add_ref(static_cast(this));
11 | }
12 | void FdrSocketClientImpl::OnFdrEvent_ReleaseRef() {
13 | intrusive_ptr_release(static_cast(this));
14 | }
15 | void FdrSocketClientImpl::OpImpl_Close() {
16 | this->State_ = State::Closing;
17 | this->EnabledEvents_.store(0, std::memory_order_relaxed);
18 | this->RemoveFdrEvent();
19 | ::shutdown(this->GetFD(), SHUT_WR);
20 | }
21 |
22 | } } // namespaces
23 | #endif
24 |
--------------------------------------------------------------------------------
/fon9/io/FdrTcpClient.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrTcpClient.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/sys/Config.h"
4 | #ifdef fon9_POSIX
5 | #include "fon9/io/FdrTcpClient.hpp"
6 |
7 | namespace fon9 { namespace io {
8 |
9 | bool FdrTcpClientImpl::OpImpl_ConnectTo(const SocketAddress& addr, SocketResult& soRes) {
10 | this->State_ = State::Connecting;
11 | if (::connect(this->GetFD(), &addr.Addr_, addr.GetAddrLen()) == 0) {
12 | this->Owner_->OpImpl_Connected(this->GetFD());
13 | }
14 | else {
15 | int eno = errno;
16 | if (eno != EINPROGRESS) {
17 | soRes = SocketResult{"connect", GetSocketErrC(eno)};
18 | return false;
19 | }
20 | this->EnableEventBit(FdrEventFlag::Writable);
21 | }
22 | return true;
23 | }
24 |
25 | void FdrTcpClientImpl::OnFdrSocket_Error(std::string errmsg) {
26 | this->Owner_->OnSocketError(this, std::move(errmsg));
27 | }
28 | void FdrTcpClientImpl::OnFdrEvent_Handling(FdrEventFlag evs) {
29 | FdrEventProcessor(this, *this->Owner_, evs);
30 | }
31 | void FdrTcpClientImpl::OnFdrEvent_StartSend() {
32 | this->StartSend(*this->Owner_);
33 | }
34 |
35 | } } // namespaces
36 | #endif
37 |
--------------------------------------------------------------------------------
/fon9/io/FdrTcpClient.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/FdrTcpClient.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_io_FdrTcpClient_hpp__
4 | #define __fon9_io_FdrTcpClient_hpp__
5 | #include "fon9/io/TcpClientBase.hpp"
6 | #include "fon9/io/FdrSocketClient.hpp"
7 |
8 | namespace fon9 { namespace io {
9 |
10 | struct FdrTcpClientImpl : public FdrSocketClientImpl {
11 | fon9_NON_COPY_NON_MOVE(FdrTcpClientImpl);
12 | using base = FdrSocketClientImpl;
13 | virtual void OnFdrEvent_Handling(FdrEventFlag evs) override;
14 | virtual void OnFdrEvent_StartSend() override;
15 | virtual void OnFdrSocket_Error(std::string errmsg) override;
16 |
17 | public:
18 | using OwnerDevice = TcpClientT;
19 | using OwnerDeviceSP = intrusive_ptr;
20 | const OwnerDeviceSP Owner_;
21 |
22 | FdrTcpClientImpl(OwnerDevice* owner, Socket&& so, SocketResult&)
23 | : base{*owner->IoService_, std::move(so)}
24 | , Owner_{owner} {
25 | }
26 | bool OpImpl_ConnectTo(const SocketAddress& addr, SocketResult& soRes);
27 | };
28 |
29 | //--------------------------------------------------------------------------//
30 |
31 | /// \ingroup io
32 | /// 使用 fd 的實作的 TcpClient.
33 | using FdrTcpClient = DeviceImpl_DeviceStartSend;
34 |
35 | } } // namespaces
36 | #endif//__fon9_io_FdrTcpClient_hpp__
37 |
--------------------------------------------------------------------------------
/fon9/io/Manager.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/Manager.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/io/Manager.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 | Manager::~Manager() {
8 | }
9 |
10 | unsigned ManagerC::IoManagerAddRef() {
11 | return intrusive_ptr_add_ref(static_cast(this));
12 | }
13 | unsigned ManagerC::IoManagerRelease() {
14 | return intrusive_ptr_release(static_cast(this));
15 | }
16 |
17 | } } // namespaces
18 |
--------------------------------------------------------------------------------
/fon9/io/SendBuffer.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/io/SendBuffer.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/io/SendBuffer.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 | } } // namespaces
8 |
--------------------------------------------------------------------------------
/fon9/io/Session.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/Session.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/io/Session.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 | Session::~Session() {
8 | }
9 | void Session::OnDevice_Initialized(Device& dev) {
10 | (void)dev;
11 | }
12 | void Session::OnDevice_Destructing(Device& dev) {
13 | (void)dev;
14 | }
15 | bool Session::OnDevice_BeforeOpen(Device& dev, std::string& cfgstr) {
16 | (void)dev; (void)cfgstr;
17 | return true;
18 | }
19 | void Session::OnDevice_StateChanged(Device& dev, const StateChangedArgs& e) {
20 | (void)dev; (void)e;
21 | }
22 | void Session::OnDevice_StateUpdated(Device& dev, const StateUpdatedArgs& e) {
23 | (void)dev; (void)e;
24 | }
25 | RecvBufferSize Session::OnDevice_LinkReady(Device& dev) {
26 | (void)dev;
27 | return RecvBufferSize::Default;
28 | }
29 | RecvBufferSize Session::OnDevice_Recv(Device& dev, DcQueue& rxbuf) {
30 | (void)dev; (void)rxbuf;
31 | return RecvBufferSize::Default;
32 | }
33 | void Session::OnDevice_CommonTimer(Device& dev, TimeStamp now) {
34 | (void)dev; (void)now;
35 | }
36 | //void Session::OnDevice_SendBufferEmpty(Device& dev) {
37 | // (void)dev;
38 | //}
39 | std::string Session::SessionCommand(Device& dev, StrView cmdln) {
40 | (void)dev; (void)cmdln;
41 | return "unknown session command";
42 | }
43 |
44 | } } // namespaces
45 |
--------------------------------------------------------------------------------
/fon9/io/TcpClientBase.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/TcpClientBase.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/io/TcpClientBase.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 | bool TcpClientBase::CreateSocket(Socket& so, const SocketAddress& addr, SocketResult& soRes) {
8 | return so.CreateDeviceSocket(addr.GetAF(), SocketType::Stream, soRes);
9 | }
10 | void TcpClientBase::OpImpl_Connected(Socket::socket_t so) {
11 | auto errc = Socket::LoadSocketErrC(so);
12 | if (errc) {
13 | OpThr_SetBrokenState(*this, RevPrintTo("err=", errc));
14 | return;
15 | }
16 | SocketAddress addrLocal;
17 | socklen_t addrLen = sizeof(addrLocal);
18 | getsockname(so, &addrLocal.Addr_, &addrLen);
19 | char uidbuf[kMaxTcpConnectionUID];
20 | StrView uidstr = MakeTcpConnectionUID(uidbuf, &this->RemoteAddress_, &addrLocal);
21 | if (this->RemoteAddress_ == addrLocal) {
22 | std::string errmsg{"err=self-connect|id="};
23 | uidstr.AppendTo(errmsg);
24 | OpThr_SetBrokenState(*this, std::move(errmsg));
25 | }
26 | else {
27 | this->OpImpl_SetConnected(uidstr.ToString());
28 | }
29 | }
30 |
31 | } } // namespaces
32 |
--------------------------------------------------------------------------------
/fon9/io/TcpClientBase.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/TcpClientBase.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_io_TcpClientBase_hpp__
4 | #define __fon9_io_TcpClientBase_hpp__
5 | #include "fon9/io/SocketClientDevice.hpp"
6 |
7 | namespace fon9 { namespace io {
8 |
9 | /// \ingroup io
10 | /// TcpClient 基底, 衍生者: IocpTcpClient, FdrTcpClient;
11 | class fon9_API TcpClientBase : public SocketClientDevice {
12 | fon9_NON_COPY_NON_MOVE(TcpClientBase);
13 | TcpClientBase() = delete;
14 | using base = SocketClientDevice;
15 |
16 | protected:
17 | bool CreateSocket(Socket& so, const SocketAddress& addr, SocketResult& soRes) override;
18 | void OpImpl_Connected(Socket::socket_t so);
19 |
20 | public:
21 | TcpClientBase(SessionSP ses, ManagerSP mgr)
22 | : base(std::move(ses), std::move(mgr), Style::Client) {
23 | }
24 | };
25 |
26 | template
27 | using TcpClientT = SocketClientDeviceT;
28 |
29 | } } // namespaces
30 | #endif//__fon9_io_TcpClientBase_hpp__
31 |
--------------------------------------------------------------------------------
/fon9/io/TcpServerBase.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/TcpServerBase.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/io/TcpServerBase.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 |
8 | } } // namespaces
9 |
--------------------------------------------------------------------------------
/fon9/io/win/IocpSocketClient.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/win/IocpSocketClient.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/io/win/IocpSocketClient.hpp"
4 |
5 | namespace fon9 { namespace io {
6 |
7 | unsigned IocpSocketClientImpl::IocpSocketAddRef() {
8 | return intrusive_ptr_add_ref(this);
9 | }
10 | unsigned IocpSocketClientImpl::IocpSocketReleaseRef() {
11 | return intrusive_ptr_release(this);
12 | }
13 |
14 | } } // namespaces
15 |
--------------------------------------------------------------------------------
/fon9/io/win/IocpSocketClient.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/io/win/IocpSocketClient.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_io_win_IocpSocketClient_hpp__
4 | #define __fon9_io_win_IocpSocketClient_hpp__
5 | #include "fon9/io/win/IocpSocket.hpp"
6 |
7 | namespace fon9 { namespace io {
8 |
9 | struct fon9_API IocpSocketClientImpl : public IocpSocket, public intrusive_ref_counter {
10 | fon9_NON_COPY_NON_MOVE(IocpSocketClientImpl);
11 |
12 | virtual unsigned IocpSocketAddRef() override;
13 | virtual unsigned IocpSocketReleaseRef() override;
14 |
15 | protected:
16 | enum class State {
17 | Idle,
18 | Closing,
19 | Connecting,
20 | Connected,
21 | };
22 | State State_{};
23 |
24 | public:
25 | IocpSocketClientImpl(IocpServiceSP iosv, Socket&& so, SocketResult& soRes)
26 | : IocpSocket(std::move(iosv), std::move(so), soRes) {
27 | }
28 | bool IsClosing() const {
29 | return this->State_ == State::Closing;
30 | }
31 | };
32 |
33 | } } // namespaces
34 | #endif//__fon9_io_win_IocpSocketClient_hpp__
35 |
--------------------------------------------------------------------------------
/fon9/rc/Rc.h:
--------------------------------------------------------------------------------
1 | // \file fon9/rc/Rc.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_rc_Rc_h__
4 | #define __fon9_rc_Rc_h__
5 | #include "fon9/sys/Config.h"
6 | #include "fon9/CStrView.h"
7 | #include
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif//__cplusplus
12 |
13 | fon9_ENUM(f9rc_RcFlag, uint16_t) {
14 | f9rc_RcFlag_NoChecksum = 0x01,
15 | };
16 |
17 | fon9_ENUM(f9rc_FunctionCode, uint8_t) {
18 | f9rc_FunctionCode_Connection = 0,
19 | f9rc_FunctionCode_SASL = 1,
20 | f9rc_FunctionCode_Logout = 2,
21 | f9rc_FunctionCode_Heartbeat = 3,
22 |
23 | f9rc_FunctionCode_SeedVisitor = 6,
24 | f9rc_FunctionCode_OmsApi = 7,
25 |
26 | /// 這裡提供一個暫時的最大值, 可減少一些記憶體用量.
27 | /// 目前規劃:
28 | /// - admin 功能(登入、Heartbeat...)
29 | /// - SeedVisitor
30 | /// - OmsRc
31 | /// - 其他請參考 fon9/rc/README.md
32 | f9rc_FunctionCode_Count = 8,
33 | };
34 |
35 | #ifdef __cplusplus
36 | }//extern "C"
37 | #endif//__cplusplus
38 | #endif//__fon9_rc_Rc_h__
39 |
--------------------------------------------------------------------------------
/fon9/rc/RcFuncConn.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/rc/RcFuncConn.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/rc/RcFuncConn.hpp"
4 |
5 | namespace fon9 { namespace rc {
6 |
7 | RcFuncConnection::~RcFuncConnection() {
8 | }
9 |
10 | } } // namespace
11 |
--------------------------------------------------------------------------------
/fon9/rc/RcMdRtsDecoder.h:
--------------------------------------------------------------------------------
1 | // \file fon9/rc/RcMdRtsDecoder.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_rc_RcMdRtsDecoder_h__
4 | #define __fon9_rc_RcMdRtsDecoder_h__
5 | #include "fon9/rc/RcSeedVisitor.h"
6 | #include "fon9/fmkt/FmdTypes.h"
7 | #include "fon9/fmkt/FmdRtsPackType.h"
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif//__cplusplus
12 |
13 | /// 將 "MdRts" 加入 StreamDecoder; 之後可以使用: "$TabName:MdRts:Args"; 的格式.
14 | /// - 在 f9sv_Initialize() 之後, f9sv_Subscribe() 之前, 執行一次即可.
15 | /// - 行情訂閱: 訂閱參數=? 如何回補? 如何區分日夜盤?
16 | /// 回補應可到「前一盤」, 不論前一盤是日盤或夜盤.
17 | f9sv_CAPI_FN(f9sv_Result) f9sv_AddStreamDecoder_MdRts(void);
18 |
19 | #ifdef __cplusplus
20 | }//extern "C"
21 | #endif//__cplusplus
22 | #endif//__fon9_rc_RcMdRtsDecoder_h__
23 |
--------------------------------------------------------------------------------
/fon9/rc/RcSvStreamDecoder.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/rc/RcSvStreamDecoder.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/rc/RcSvStreamDecoder.hpp"
4 |
5 | namespace fon9 { namespace rc {
6 |
7 | RcSvStreamDecoderNote::~RcSvStreamDecoderNote() {
8 | }
9 | RcSvStreamDecoder::~RcSvStreamDecoder() {
10 | }
11 | RcSvStreamDecoderFactory::~RcSvStreamDecoderFactory() {
12 | }
13 | RcSvStreamDecoderFactory* RcSvStreamDecoderPark::Register(StrView name, RcSvStreamDecoderFactory* factory) {
14 | return SimpleFactoryRegister(name, factory);
15 | }
16 |
17 |
18 | } } // namespaces
19 |
--------------------------------------------------------------------------------
/fon9/seed/Field.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/Field.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/Field.hpp"
4 | #include "fon9/seed/FieldTimeStamp.hpp"
5 |
6 | namespace fon9 { namespace seed {
7 |
8 | Field::~Field() {
9 | }
10 | uint32_t Field::GetAvailSize() const {
11 | return this->Size_;
12 | }
13 | FieldNumberT Field::GetNullValue() const {
14 | return 0;
15 | }
16 | OpResult Field::SetNull(const RawWr& wr) const {
17 | (void)wr;
18 | return OpResult::not_supported_null;
19 | }
20 | bool Field::IsNull(const RawRd& rd) const {
21 | (void)rd;
22 | return false;
23 | }
24 |
25 | //--------------------------------------------------------------------------//
26 |
27 | StrView FieldTimeStamp::GetTypeId(NumOutBuf&) const {
28 | return StrView{"Ts"};
29 | }
30 | StrView FieldTimeInterval::GetTypeId(NumOutBuf&) const {
31 | return StrView{"Ti"};
32 | }
33 | StrView FieldDayTime::GetTypeId(NumOutBuf&) const {
34 | return StrView{"Td"};
35 | }
36 |
37 | } } // namespaces
38 |
--------------------------------------------------------------------------------
/fon9/seed/FieldSchCfgStr.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/FieldSchCfgStr.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/FieldSchCfgStr.hpp"
4 | #include "fon9/seed/FieldDyBlob.hpp"
5 |
6 | namespace fon9 { namespace seed {
7 |
8 | StrView FieldSchCfgStr::GetTypeId(NumOutBuf&) const {
9 | return StrView{fon9_kCSTR_UDStrFieldMaker_Head fon9_kCSTR_UDFieldMaker_SchCfgStr};
10 | }
11 |
12 | static FieldSP SchCfgStrFieldMaker(StrView& fldcfg, char chSpl, char chTail) {
13 | Named named{DeserializeNamed(fldcfg, chSpl, chTail)};
14 | if (named.Name_.empty())
15 | return FieldSP{};
16 | using FieldSchCfgStr_Dy = FieldSchCfgStrT;
17 | return FieldSP{new FieldSchCfgStr_Dy(std::move(named), f9sv_FieldType_Chars)};
18 | }
19 |
20 | static FieldMakerRegister reg{StrView{fon9_kCSTR_UDFieldMaker_SchCfgStr}, &SchCfgStrFieldMaker};
21 |
22 | } } // namespaces
23 |
--------------------------------------------------------------------------------
/fon9/seed/FieldType.h:
--------------------------------------------------------------------------------
1 | // \file fon9/seed/FieldType.h
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_seed_FieldType_h__
4 | #define __fon9_seed_FieldType_h__
5 | #include "fon9/rc/RcClientApi.h"
6 | #include "fon9/Assert.h"
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | /// \ingroup seed
13 | /// 欄位儲存的資料類型.
14 | fon9_ENUM(f9sv_FieldType, uint8_t) {
15 | /// 類型不明, 或自訂欄位.
16 | f9sv_FieldType_Unknown,
17 | /// bytes 陣列.
18 | /// 顯示字串 = 需要額外轉換(例: HEX, Base64...)
19 | f9sv_FieldType_Bytes,
20 | /// 字元串(尾端不一定會有EOS).
21 | /// 顯示字串 = 直接使用內含字元, 直到EOS or 最大長度.
22 | f9sv_FieldType_Chars,
23 |
24 | /// 整數欄位.
25 | /// >= f9sv_FieldType_Integer 之後皆為數字型別.
26 | f9sv_FieldType_Integer = 10,
27 | /// 固定小數位欄位: fon9::Decimal
28 | f9sv_FieldType_Decimal,
29 | /// 時間戳.
30 | f9sv_FieldType_TimeStamp,
31 | /// 時間間隔.
32 | f9sv_FieldType_TimeInterval,
33 | /// 時間: 距離 00:00:00 的時間間隔.
34 | /// 輸出格式 `days-hh:mm:ss.uuuuuu`
35 | f9sv_FieldType_DayTime,
36 | };
37 | static inline int f9sv_IsFieldTypeNumber(f9sv_FieldType v) {
38 | return v >= f9sv_FieldType_Integer;
39 | }
40 |
41 | /// 小數位數.
42 | typedef uint8_t f9sv_DecScale;
43 |
44 | #ifdef __cplusplus
45 | }//extern "C"
46 | #endif
47 | #endif//__fon9_seed_FieldType_h__
48 |
--------------------------------------------------------------------------------
/fon9/seed/NamedPark.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/NamedPark.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/NamedPark.hpp"
4 |
5 | namespace fon9 { namespace seed {
6 |
7 | void ParkTree::OnMaTree_AfterRemove(Locker&, NamedSeed& seed) {
8 | this->Subj_.Publish(&seed, EventType::Remove);
9 | }
10 | void ParkTree::OnMaTree_AfterAdd(Locker&, NamedSeed& seed) {
11 | this->Subj_.Publish(&seed, EventType::Add);
12 | }
13 | void ParkTree::OnMaTree_AfterClear() {
14 | Locker locker{this->Container_};
15 | this->Subj_.Publish(nullptr, EventType::Clear);
16 | }
17 |
18 | } } // namespaces
19 |
--------------------------------------------------------------------------------
/fon9/seed/Raw.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/Raw.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/Raw.hpp"
4 | #include "fon9/Blob.h"
5 |
6 | namespace fon9 { namespace seed {
7 |
8 | Raw::~Raw() {
9 | if (uint32_t L = this->GetDyBlobCount()) {
10 | byte* blobPtr = reinterpret_cast(this) + this->DyMemPos_;
11 | do {
12 | // 為了避免 blobPtr 記憶體沒有對齊, 所以複製一份處理.
13 | fon9_Blob blob = GetUnaligned(reinterpret_cast(blobPtr));
14 | fon9_Blob_Free(&blob);
15 | blobPtr += sizeof(fon9_Blob);
16 | } while (--L > 0);
17 | }
18 | }
19 |
20 | } } // namespaces
21 |
--------------------------------------------------------------------------------
/fon9/seed/SeedAclTree.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/SeedAclTree.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/SeedAcl.hpp"
4 | #include "fon9/seed/FieldMaker.hpp"
5 |
6 | namespace fon9 { namespace seed {
7 |
8 | static Fields MakeAclTreeFields() {
9 | Fields fields;
10 | fields.Add(fon9_MakeField(AccessList::value_type, second.Rights_, "Rights"));
11 | fields.Add(fon9_MakeField(AccessList::value_type, second.MaxSubrCount_, "MaxSubrCount"));
12 | return fields;
13 | }
14 | static LayoutSP MakeAclTreeLayout(TabFlag tabFlags, TreeFlag treeFlags) {
15 | return LayoutSP{new Layout1(fon9_MakeField(AccessList::value_type, first, "Path"),
16 | new Tab{Named{"AclRights"}, MakeAclTreeFields(), tabFlags},
17 | treeFlags)};
18 | }
19 | fon9_API LayoutSP MakeAclTreeLayout() {
20 | static LayoutSP aclLayout{MakeAclTreeLayout(TabFlag::NoSapling, TreeFlag{})};
21 | return aclLayout;
22 | }
23 | fon9_API LayoutSP MakeAclTreeLayoutWritable() {
24 | static LayoutSP aclLayout{MakeAclTreeLayout(TabFlag::NoSapling | TabFlag::Writable, TreeFlag::AddableRemovable)};
25 | return aclLayout;
26 | }
27 |
28 | } } // namespaces
29 |
--------------------------------------------------------------------------------
/fon9/seed/Tree.cpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/seed/Tree.cpp
2 | /// \author fonwinz@gmail.com
3 | #include "fon9/seed/Tree.hpp"
4 |
5 | namespace fon9 { namespace seed {
6 |
7 | Tree::~Tree() {
8 | }
9 |
10 | void Tree::OnTreeReleased() {
11 | if (this->use_count() == 0)
12 | delete this;
13 | }
14 |
15 | void Tree::OnTreeOp(FnTreeOp fnCallback) {
16 | fnCallback(TreeOpResult{this, OpResult::not_supported_tree_op}, nullptr);
17 | }
18 |
19 | void Tree::OnTabTreeOp(FnTreeOp fnCallback) {
20 | fnCallback(TreeOpResult{this, OpResult::not_supported_tree_op}, nullptr);
21 | }
22 |
23 | void Tree::OnParentSeedClear() {
24 | }
25 |
26 | } } // namespaces
27 |
--------------------------------------------------------------------------------
/fon9/sys/OnWindowsMainExit.hpp:
--------------------------------------------------------------------------------
1 | /// \file fon9/sys/OnWindowsMainExit.hpp
2 | /// \author fonwinz@gmail.com
3 | #ifndef __fon9_sys_OnWindowsMainExit_hpp__
4 | #define __fon9_sys_OnWindowsMainExit_hpp__
5 |
6 | namespace fon9 { namespace sys {
7 |
8 | #if defined(_MSC_VER) && defined(_DLL)
9 | #define fon9_HAVE_OnWindowsMainExitHandle
10 | /// 如果 libfon9 是 Windows DLL, 則需要:
11 | /// - 在 exe.main() 結束後 & libfon9.dll 卸載前: 主動關閉 fon9 內部的 thread(例: MemBlock::Center).
12 | /// - 否則在 libfon9.dll 卸載前, thread 會被強制結束! 無法安全的清理 thread 裡面的資源!
13 | struct OnWindowsMainExitHandle {
14 | OnWindowsMainExitHandle();
15 | virtual void OnWindowsMainExit_Notify() = 0;
16 | virtual void OnWindowsMainExit_ThreadJoin() = 0;
17 | protected:
18 | virtual ~OnWindowsMainExitHandle();
19 | };
20 | /// 通常在 API 結束時呼叫, 例如: RcClientApi.cpp: fon9_Finalize();
21 | void OnWindowsMainExit_When_No_atexit();
22 | #else
23 | struct OnWindowsMainExitHandle {
24 | };
25 | #endif
26 |
27 | } } // namespaces
28 |
29 | #endif//__fon9_sys_OnWindowsMainExit_hpp__
30 |
--------------------------------------------------------------------------------
/fon9/web/HtmlEncoder.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/web/HtmlEncoder.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/web/HtmlEncoder.hpp"
4 | #include "fon9/RevPrint.hpp"
5 |
6 | namespace fon9 { namespace web {
7 |
8 | fon9_API void RevEncodeHtml(RevBuffer& rbuf, StrView str) {
9 | const char* const pbeg = str.begin();
10 | for (const char* pend = str.end(); pend != pbeg;) {
11 | const char ch = *--pend;
12 | switch (ch) {
13 | case '&': RevPrint(rbuf, "&"); break;
14 | case '<': RevPrint(rbuf, "<"); break;
15 | case '>': RevPrint(rbuf, ">"); break;
16 | default: RevPutChar(rbuf, ch); break;
17 | }
18 | }
19 | }
20 |
21 | } } // namespace
22 |
--------------------------------------------------------------------------------
/fon9/web/HtmlEncoder.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/web/HtmlEncoder.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_web_HtmlEncoder_hpp__
4 | #define __fon9_web_HtmlEncoder_hpp__
5 | #include "fon9/buffer/RevBuffer.hpp"
6 |
7 | namespace fon9 { namespace web {
8 |
9 | /// 將 str 的特殊字元(例: '<', '>', '&') 轉換成 HTML 編碼(例: "<", ">", "&").
10 | fon9_API void RevEncodeHtml(RevBuffer& rbuf, StrView str);
11 |
12 | } } // namespaces
13 | #endif//__fon9_web_HtmlEncoder_hpp__
14 |
--------------------------------------------------------------------------------
/fon9/web/HttpDate.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/web/HttpDate.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_web_HttpDate_hpp__
4 | #define __fon9_web_HttpDate_hpp__
5 | #include "fon9/TimeStamp.hpp"
6 |
7 | namespace fon9 { namespace web {
8 |
9 | fon9_API TimeStamp HttpDateTo(StrView str);
10 |
11 | enum : size_t {
12 | kHttpDateWidth = sizeof("Sun, 06 Nov 1994 08:49:37 GMT") -1,
13 | };
14 | /// day-name "," SP date1 SP time-of-day SP GMT
15 | fon9_API char* ToHttpDateRev(char* pout, TimeStamp ts);
16 |
17 | struct FmtHttpDate {
18 | TimeStamp TS_;
19 | };
20 | inline char* ToStrRev(char* pout, const FmtHttpDate& httpts) {
21 | return ToHttpDateRev(pout, httpts.TS_);
22 | }
23 |
24 | } } // namespaces
25 | #endif//__fon9_web_HttpDate_hpp__
26 |
--------------------------------------------------------------------------------
/fon9/web/HttpParser.hpp:
--------------------------------------------------------------------------------
1 | // \file fon9/web/HttpParser.hpp
2 | // \author fonwinz@gmail.com
3 | #ifndef __fon9_web_HttpParser_hpp__
4 | #define __fon9_web_HttpParser_hpp__
5 | #include "fon9/web/HttpMessage.hpp"
6 | #include "fon9/buffer/DcQueue.hpp"
7 |
8 | namespace fon9 { namespace web {
9 |
10 | enum : size_t {
11 | /// strlen("chunk-size[chunk-ext]\r\n");
12 | kHttpMaxChunkLineLength = 64,
13 | kHttpMaxChunkedSize = 1024 * 1024 * 8,
14 | };
15 |
16 | enum class HttpResult {
17 | HeaderTooLarge = -1,
18 | BadChunked = -2,
19 | /// chunked size 超過 kHttpMaxChunkedSize
20 | ChunkSizeTooLarge = -3,
21 | ChunkSizeLineTooLong = -4,
22 | Incomplete = 0,
23 | FullMessage = 1,
24 | ChunkAppended = 2,
25 | };
26 |
27 | struct fon9_API HttpParser {
28 | static HttpResult Feed(HttpMessage& msg, DcQueue& buf);
29 | static HttpResult ContinueEat(HttpMessage& msg);
30 |
31 | private:
32 | static HttpResult AfterFeedBody(HttpMessage& msg);
33 | static HttpResult AfterFeedHeader(HttpMessage& msg, size_t bfsz);
34 | static HttpResult ParseChunk(HttpMessage& msg);
35 | static HttpResult CheckChunkAppend(HttpMessage& msg);
36 | static HttpResult FetchNextChunkSize(HttpMessage& msg);
37 | static HttpResult FetchChunkTrailer(HttpMessage& msg);
38 | };
39 |
40 | } } // namespaces
41 | #endif//__fon9_web_HttpParser_hpp__
42 |
--------------------------------------------------------------------------------
/fon9/web/UrlCodec.cpp:
--------------------------------------------------------------------------------
1 | // \file fon9/web/UrlCodec.cpp
2 | // \author fonwinz@gmail.com
3 | #include "fon9/web/UrlCodec.hpp"
4 |
5 | namespace fon9 { namespace web {
6 |
7 | fon9_API void UrlEncodeAppend(std::string& dst, const StrView& src) {
8 | UrlEncodeAppend(dst, src);
9 | }
10 | fon9_API void UrlEncodeAppend(CharVector& dst, const StrView& src) {
11 | UrlEncodeAppend(dst, src);
12 | }
13 |
14 | //--------------------------------------------------------------------------//
15 |
16 | fon9_API void UrlDecodeAppend(std::string& dst, const StrView& src) {
17 | UrlDecodeAppend(dst, src);
18 | }
19 | fon9_API void UrlDecodeAppend(CharVector& dst, const StrView& src) {
20 | UrlDecodeAppend(dst, src);
21 | }
22 |
23 | } } // namespace
24 |
--------------------------------------------------------------------------------
/fon9/web/ma/gv.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fonwin/libfon9/c07ca2ffb3547a03a31c41db5ad036ab6ee859bc/fon9/web/ma/gv.css
--------------------------------------------------------------------------------
/fon9/web/ma/logo-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fonwin/libfon9/c07ca2ffb3547a03a31c41db5ad036ab6ee859bc/fon9/web/ma/logo-40.png
--------------------------------------------------------------------------------
/make_proj_verinfo.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | REM 在指定路徑建立 proj_verinfo.h:
4 | REM - Windows 在「Build Events/Pre-Build Event/Command Line」設定:
5 | REM cd 「proj_verinfo.h 存放路徑」 (例如 cd ..\..\..\YourProjectName)
6 | REM call ..\fon9\make_proj_verinfo.bat
7 | REM - 然後可以在程式裡將版本資放入 SysEnv:
8 | REM if (auto sysEnv = holder.Root_->Get(fon9_kCSTR_SysEnv_DefaultName))
9 | REM fon9::seed::LogSysEnv(sysEnv->Add(new fon9::seed::SysEnvItem("Version", proj_VERSION)).get());
10 |
11 |
12 | FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime/VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET ldt=%%j
13 | SET ldt=%ldt:~0,4%.%ldt:~4,2%.%ldt:~6,2%-%ldt:~8,2%%ldt:~10,2%
14 |
15 | pushd %~dp0
16 | FOR /F "tokens=*" %%g IN ('git rev-parse "--short=12" HEAD') DO SET FON9_HASH=%%g
17 | popd
18 |
19 | FOR /F "tokens=*" %%g IN ('git rev-parse "--short=12" HEAD') DO SET MySln_HASH=%%g
20 |
21 | SET pwd=%CD%
22 | For %%A in ("%pwd%") do SET PROJ=%%~nxA
23 |
24 | echo #ifndef proj_NAME> proj_verinfo.h
25 | echo #define proj_NAME "%PROJ%">> proj_verinfo.h
26 | echo #endif>> proj_verinfo.h
27 | echo #define proj_VERSION proj_NAME "=%MySln_HASH%|fon9=%FON9_HASH%|build=%ldt%">> proj_verinfo.h
28 |
29 |
--------------------------------------------------------------------------------
/make_proj_verinfo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # 在指定路徑建立 proj_verinfo.h:
5 | # - Linux 在 CMakeLists.txt 裡面執行:
6 | # execute_process(COMMAND "../fon9/make_proj_verinfo.sh" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
7 | # RESULT_VARIABLE ret)
8 | # if(NOT ret EQUAL 0)
9 | # message(FATAL_ERROR "Run make_proj_verionf.sh ERROR: " ${ret})
10 | # endif()
11 | #
12 | # - 然後可以在程式裡將版本資放入 SysEnv:
13 | # if (auto sysEnv = holder.Root_->Get(fon9_kCSTR_SysEnv_DefaultName))
14 | # fon9::seed::LogSysEnv(sysEnv->Add(new fon9::seed::SysEnvItem("Version", proj_VERSION)).get());
15 | #
16 |
17 | pushd $(dirname "$0")
18 | FON9_HASH=`git rev-parse --short=12 HEAD | xargs`
19 | popd
20 |
21 | MySln_HASH=`git rev-parse --short=12 HEAD | xargs`
22 |
23 | BUILDTM=`date +"%Y.%m.%d-%H%M"`
24 |
25 | PROJ=`basename "${PWD}"`
26 |
27 | echo "#ifndef proj_NAME" > proj_verinfo.h
28 | echo "#define proj_NAME \"${PROJ}\"" >> proj_verinfo.h
29 | echo "#endif" >> proj_verinfo.h
30 | echo "#define proj_VERSION proj_NAME \"=${MySln_HASH}|fon9=${FON9_HASH}|build=${BUILDTM}\"" >> proj_verinfo.h
31 |
--------------------------------------------------------------------------------
/make_static_o.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # 因為無法指定 .a 檔案的 export symbols; (我不知到有什麼更簡單的方法).
4 | # 所以用底下的方法, 建立一個特殊的 .o 檔案, 用來取代 .a;
5 | # 執行時必須提供3個參數:
6 | # dst.o src.a 建立so時的version-script
7 | #
8 |
9 | set -e
10 | dst=$1
11 | src=$2
12 | expsrc=$3
13 |
14 | echo Building [$dst] for static link.
15 |
16 | tmpdir=$dst.tmpd
17 | rm -rf $tmpdir
18 | mkdir $tmpdir
19 | cp $src $tmpdir/tmp.a
20 | pushd $tmpdir >/dev/null
21 | ar x tmp.a
22 | ld -r -o tmp.ro *.o
23 | popd >/dev/null
24 |
25 | sed 's/[ {}]//g' $expsrc |sed 's/;/\n/g' >$tmpdir/exports.txt
26 | objcopy $tmpdir/tmp.ro $dst --keep-global-symbols=$tmpdir/exports.txt
27 | strip -x $dst
28 |
29 | rm -rf $tmpdir
30 |
31 | echo [$dst] is ready for static link.
32 |
--------------------------------------------------------------------------------