📄 channel.h
字号:
// ------------------------------------------------// File : channel.h// Date: 4-apr-2002// Author: giles//// (c) 2002 peercast.org// ------------------------------------------------// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// ------------------------------------------------#ifndef _CHANNEL_H#define _CHANNEL_H#include "sys.h"#include "stream.h"#include "gnutella.h"#include "xml.h"// --------------------------------------------------struct MP3Header{ int lay; int version; int error_protection; int bitrate_index; int sampling_frequency; int padding; int extension; int mode; int mode_ext; int copyright; int original; int emphasis; int stereo;};// ----------------------------------class OggPacket{public: enum { MAX_DATALEN = 16384 }; void read(Stream &); bool isBOS(); void *getContent() { return &data[27+numSegs]; } int getContentLen() { return segLen; } bool isVorbisPacket(); int getVorbisType(); int len,numSegs,segLen; unsigned char data[MAX_DATALEN];};// ----------------------------------class TrackInfo{public: void clear() { contact.clear(); title.clear(); artist.clear(); album.clear(); genre.clear(); } void convertTo(String::TYPE t) { contact.convertTo(t); title.convertTo(t); artist.convertTo(t); album.convertTo(t); genre.convertTo(t); } ::String contact,title,artist,album,genre;};// ----------------------------------class ChanInfo{public: enum TYPE { T_UNKNOWN, T_RAW, T_MP3, T_OGG, T_MOV, T_MPG, T_PEERCAST, T_NSV, T_PLAYLIST }; enum STATUS { S_UNKNOWN, S_PLAY }; ChanInfo() {init();} void init(); void init(const char *); void init(const char *, GnuID &, TYPE, int); void init(XML::Node *); void initNameID(const char *); void updateFromXML(XML::Node *); void readTrackXML(XML::Node *); void readServentXML(XML::Node *); void update(ChanInfo &); XML::Node *createQueryXML(); XML::Node *createChannelXML(); XML::Node *createRelayChannelXML(); XML::Node *createTrackXML(); bool match(XML::Node *); bool match(ChanInfo &); bool isActive() {return id.isSet();} static const char *getTypeStr(int); static const char *getTypeExt(int); static TYPE getTypeFromStr(const char *str); ::String name; GnuID id; int bitrate; TYPE srcType,contentType; unsigned int lastPlay; unsigned int numSkips; STATUS status; TrackInfo track; ::String desc,genre,url,comment;};// ----------------------------------class ChanHit{public: void init(); Host host; int numListeners; bool firewalled,busy,stable; int index; int hops; int numSkips; unsigned int time,upTime; char agentStr[16]; int maxPreviewTime; GnuID packetID;};// ----------------------------------class ChanHitList{public: enum { MAX_HITS = 200 }; void init(); ChanHit *addHit(ChanHit &); void deadHit(ChanHit &); int numHits(); int numListeners(); int numBusy(); int numStable(); int numFirewalled(); int closestHit(); int furthestHit(); unsigned int newestHit(); ChanHit getHit(bool); bool isUsed() {return info.isActive();} bool isAvailable(); int clearDeadHits(unsigned int); XML::Node *createHitsXML(); ChanInfo info; ChanHit hits[MAX_HITS]; unsigned int lastHitTime; int index; bool locked;};// ----------------------------------class ChanPacket{public: enum { MAX_DATALEN = 16384 }; void init(unsigned int t, const void *p, unsigned int l); void write(Stream &); void read(Stream &); unsigned int type; unsigned int len; char data[MAX_DATALEN];};// ----------------------------------class ChanPacketBuffer {public: enum { MAX_PACKETS = 32 }; void init() {currPacket = lastPacket = firstPacket = 0;} void writePacket(ChanPacket &); unsigned int readPacket(unsigned int,ChanPacket &); ChanPacket packets[MAX_PACKETS]; unsigned int currPacket,lastPacket,firstPacket; WLock lock;};#if 0// ----------------------------------class ChanBuffer {public: enum { MAX_DATALEN = 65536 }; void init() {pos=lastPacket=firstPacket=0;} unsigned int read(unsigned int,void *,unsigned int); void write(const void *,int); void writePacket(ChanPacket &); unsigned int readPacket(unsigned int,ChanPacket &); unsigned int pos,lastPacket,firstPacket; char data[MAX_DATALEN]; WLock lock;};#endif// ----------------------------------class ChanMeta{public: enum { MAX_DATALEN = 65536 }; void init() { len = 0; cnt = 0; } void fromXML(XML &); void fromMem(void *,int); void addMem(void *,int); unsigned int len,cnt; char data[MAX_DATALEN];};// ----------------------------------class Channel{public: enum STATUS { S_NONE, S_WAIT, S_CONNECTING, S_REQUESTING, S_CLOSING, S_RECEIVING, S_BROADCASTING, S_ABORT, S_SEARCHING, S_NOHOSTS, S_IDLE, S_ERROR }; enum TYPE { T_NONE, T_ALLOCATED, T_BROADCAST, T_RELAY }; enum SRC_TYPE { SRC_NONE, SRC_PEERCAST, SRC_SHOUTCAST, SRC_ICECAST, SRC_URL }; void init(); void reset(); void close(); void endThread(); void startMP3File(char *); void startGet(); void startICY(ClientSocket *,SRC_TYPE); void startFind(); void startURL(const char *); bool isPlaying() { return (status == S_RECEIVING) || (status == S_BROADCASTING); } bool isReceiving() { return (status == S_RECEIVING); } bool isBroadcasting() { return (status == S_BROADCASTING); } bool isFull(); bool checkBump() { if (bump) { bump = false; return true; }else return false; } bool checkIdle(); bool isActive() { return type != T_NONE; } bool isIdle() {return isActive() && (status==S_IDLE);} static THREAD_PROC streamMP3File(ThreadInfo *); static THREAD_PROC streamGet(ThreadInfo *); static THREAD_PROC streamICY(ThreadInfo *); static THREAD_PROC streamURL(ThreadInfo *); static THREAD_PROC findProc(ThreadInfo *); ::String streamURL(const char *); void setStatus(STATUS s); const char *getSrcTypeStr() {return srcTypes[srcType];} const char *getStatusStr() {return statusMsgs[status];} const char *getName() {return info.name.cstr();} GnuID getID() {return info.id;} int getBitrate() {return info.bitrate; } void getIDStr(char *s) {info.id.toStr(s);} void getStreamPath(char *); void updateMeta(); void readStream(); void readOGG(); void readMP3(); void readRaw(); void readPeercast(); void readMOV(); void readMPG(); void processMetadata(char *); void processOggComment(OggPacket &); void processOggIdent(OggPacket &); void readHeader(); void readOggHeader(); XML::Node *createRelayXML(bool); void giveSocket(ClientSocket *s) { if (!pushSock) pushSock = s; } ::String mount; ChanMeta headMeta,insertMeta; ChanPacketBuffer chanData; int numRelays,numListeners; ChanInfo info; ChanHit currSource; ::String sourceURL; bool bump,stayConnected; int icyMetaInterval; unsigned int syncPos; int readDelay; TYPE type; Stream *input; SRC_TYPE srcType; MP3Header mp3Head; ThreadInfo thread; unsigned int lastIdleTime,prefetchCnt; int index; int status; static char *statusMsgs[],*srcTypes[]; ClientSocket *sock; ClientSocket *pushSock; int pushIndex;};// ----------------------------------class ChanMgr{public: enum { MAX_CHANNELS = 16, MAX_IDLE = 8, MAX_HITLISTS = 200 }; ChanMgr(); Channel *createChannel(ChanInfo &,const char *); Channel *findChannelByName(const char *); Channel *findChannelByIndex(int); Channel *findChannelByMount(const char *); Channel *findChannelByID(GnuID &); Channel *findPushChannel(int); Channel *findChannel(ChanInfo &); Channel *findListenerChannel(); void broadcastRelays(int,Servent *); int findChannels(ChanInfo &,Channel **,int); int findChannelsByStatus(Channel **,int,Channel::STATUS); int numConnected(); int numRelayed(); int numListeners(); int numIdle(); unsigned int totalInput(); ChanHit *addHit(ChanInfo &, ChanHit &); void setFirewalled(Host &); ChanHitList *findHitList(ChanInfo &); ChanHitList *findHitListByID(GnuID &id); ChanHitList *addHitList(ChanInfo &); void clearHitLists(); void clearDeadHits(); int numHitLists(); void lockHitList(GnuID &,bool); void setBroadcastMsg(::String &); Channel *createRelay(ChanInfo &,bool); int findAndRelay(ChanInfo &,Channel **,int); void startSearch(ChanInfo &); void playChannels(Channel **,int); void playChannel(GnuID &,bool); Channel channels[MAX_CHANNELS]; ChanHitList hitlists[MAX_HITLISTS]; GnuID broadcastID; ChanInfo searchInfo; int numFinds; ::String broadcastMsg; unsigned int broadcastMsgInterval; unsigned int lastHit,lastSearch; bool searchActive; unsigned int deadHitAge; int icyMetaInterval; int maxStreamsPerChannel; WLock lock; int broadcastTTL; int pushTimeout,pushTries,maxPushHops;};// ----------------------------------class PlayList{public: enum TYPE { T_NONE, T_SCPLS, T_PLS }; PlayList(TYPE t, int max) { maxURLs = max; numURLs = 0; type = t; urls = new ::String[max]; titles = new ::String[max]; } ~PlayList() { delete [] urls; delete [] titles; } void addURL(const char *url, const char *tit) { if (numURLs < maxURLs) { urls[numURLs].set(url); titles[numURLs].set(tit); numURLs++; } } void addChannels(const char *,Channel **,int); void addChannel(const char *,ChanInfo &); void writeSCPLS(Stream &); void writePLS(Stream &); void write(Stream &s) { switch (type) { case T_SCPLS: writeSCPLS(s); break; case T_PLS: writePLS(s); break; } } TYPE type; int numURLs,maxURLs; ::String *urls,*titles;};// ----------------------------------extern ChanMgr *chanMgr;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -