BCode解码练习
在学习BT协议中的一个小练习
参考了 https://github.com/airtrack/bitwave
具体B编码解释 可以自行搜索或者参考 这篇文章
bittorrent 学习(一) 种子文件分析与bitmap位图
代码
#pragma once
#include "pre.h"
#include <string>
#include <vector>
#include <iostream>
#include <list>
#include <map> NAMESPACE(DEF) class BCode
{
public:
enum BCODE_TYPE {
BCODE_BASE_TYPE = ,
BCODE_STRING_TYPE = ,
BCODE_INTENGER_TYPE = ,
BCODE_LIST_TYPE = ,
BCODE_DICT_TYPE =
}; BCode(BCODE_TYPE type);
BCODE_TYPE GetBCodeType()const { return type_; }
virtual ~BCode(); protected:
BCODE_TYPE type_;
long long begin_;
long long end_;
}; class BCodeString :public BCode {
public:
explicit BCodeString(long long& begin, long long& end,
const std::vector<char>& data); bool ReadString(long long& begin,long long& end,int stringLen );
int ReadStringLen(long long& begin, long long& end);
std::string std_string() { return bcodeStr_; }
private:
const std::vector<char>& data_;
std::string bcodeStr_;
}; class BCodeIntenger :public BCode {
public:
explicit BCodeIntenger(long long& begin, long long& end,
const std::vector<char>& data); private:
const std::vector<char>& data_;
long long bcodeInt_;
}; class BCodeList :public BCode {
public:
typedef std::list<std::shared_ptr<BCode>> BCodeLists;
explicit BCodeList(long long& begin, long long& end,
const std::vector<char>& data); private:
BCodeList(const BCodeList&) = delete;
BCodeList& operator=(const BCodeList&) = delete;
BCodeLists bcodeList_;
const std::vector<char>& data_;
}; class BCodeDictionary :public BCode {
public:
typedef std::map<std::string, std::shared_ptr<BCode> > BCodemap;
typedef BCodemap::value_type pair_type; explicit BCodeDictionary(long long& begin, long long& end,
const std::vector<char>& data);
private:
BCodeDictionary(const BCodeDictionary&) = delete;
BCodeDictionary& operator=(const BCodeDictionary&) = delete;
const std::vector<char>& data_;
BCodemap bcodeMap_;
}; std::shared_ptr<BCode> GetBCodeObject(long long& begin,
long long& end,const std::vector<char>& data); NAMESPACEEND(DEF)
BCode.h
#include "BCode.h" NAMESPACE(DEF) BCode::BCode(BCODE_TYPE type)
:type_(type),begin_(),end_(){} BCode::~BCode(){} bool BCodeString::ReadString(
long long& begin,
long long& end,
int stringLen)
{
bool b = false;
long long stringEnd = begin + stringLen;
if (stringEnd > end) {
std::cerr << __FUNCTION__ << ". string range error!" << std::endl;
return b;
}
bcodeStr_.assign(&data_[begin], stringLen);
begin = stringEnd;
#ifdef _DEBUG_PRINT
std::cout << __FUNCTION__ << ". BCodeString = "
<< bcodeStr_ << std::endl; #endif // DEBUG b = true;
return b;
} BCodeString::BCodeString(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeStr_(), BCode(BCODE_STRING_TYPE), data_(data)
{
begin_ = begin;
int stringLen = ReadStringLen(begin, end);
if (stringLen <= || begin >= end || data_[begin] != ':') {
std::cerr << __FUNCTION__ << ". string length error!" << std::endl;
return;
}
begin++;
ReadString(begin, end, stringLen);
end_ = begin;
} int BCodeString::ReadStringLen(
long long& begin,
long long& end)
{
std::vector<char> tmp;
if (isdigit(data_[begin]) == ) {
std::cerr << __FUNCTION__ << ". read num error!" << std::endl;
return ;
}
while (begin != end && isdigit(data_[begin])) {
tmp.push_back(data_[begin++]);
}
return atoi(&tmp[]);
} BCodeIntenger::BCodeIntenger(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeInt_(), BCode(BCODE_INTENGER_TYPE), data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'i') {
std::cerr << __FUNCTION__ << ". intenger flag error!" << std::endl;
return;
}
++begin; //skip 'i' std::string intstr;
std::vector<char> tmp;
while (begin != end && data_[begin] != 'e' ) {
if (!isdigit(data_[begin])) {
std::cerr << __FUNCTION__ << ". get intenger error!" << std::endl;
return;
}
tmp.push_back(data_[begin++]);
}
end_ = begin;
++begin; //skip 'e'
if (begin > end) {
std::cerr << __FUNCTION__ << ". range error!" << std::endl;
return;
} bcodeInt_ = _atoi64(&tmp[]); #ifdef _DEBUG_PRINT
std::cout << __FUNCTION__ << ". BCodeIntenger = "
<< bcodeInt_ << std::endl;
#endif // DEBUG
} BCodeList::BCodeList(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeList_(), BCode(BCODE_LIST_TYPE),data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'l') {
std::cerr << __FUNCTION__ << ". BCodeList error!" << std::endl;
return;
}
++begin;
#ifdef _DEBUG_PRINT
std::cout << "start List" << std::endl;
#endif // _DEBUG while (begin != end && data_[begin] != 'e') {
bcodeList_.push_back(GetBCodeObject(begin,end,data_));
}
end_ = begin;
if (begin >= end || data[end_] != 'e' ) {
std::cerr << __FUNCTION__ << ". BCodeList end error!" << std::endl;
return;
} ++begin;
#ifdef _DEBUG_PRINT
std::cout << "end List" << std::endl;
#endif // _DEBUG
} BCodeDictionary::BCodeDictionary(long long& begin, long long& end,
const std::vector<char>& data)
:bcodeMap_(), BCode(BCODE_DICT_TYPE), data_(data)
{
begin_ = begin;
if (begin >= end || data_[begin] != 'd') {
std::cerr << __FUNCTION__ << ". range error!" << std::endl;
return;
}
++begin; //skip 'd'
#ifdef _DEBUG_PRINT
std::cout << "dict start " << std::endl;
#endif
while (begin != end && data[begin] != 'e') {
#ifdef _DEBUG_PRINT
std::cout << "key is ";
#endif
BCodeString key(begin, end,data);
std::shared_ptr<BCode> value = GetBCodeObject(begin,end,data);
if (value) {
bcodeMap_.insert(BCodemap::value_type(key.std_string(), value));
}
}
#ifdef _DEBUG_PRINT
std::cout << "dict end " << std::endl;
#endif
end_ = begin;
if (begin >= end || data[end_] != 'e') {
std::cerr << __FUNCTION__ << ". BCodeDictionary end error!" << std::endl;
return;
}
++begin; //skip 'e' return;
} std::shared_ptr<BCode> GetBCodeObject(long long& begin,
long long& end, const std::vector<char>& data) {
if (begin >= end || end > data.size()) {
std::cerr << __FUNCTION__ << ". Range error!" << std::endl;
return NULL;
} switch (data[begin]) {
case 'i':
return std::shared_ptr<BCode>(new BCodeIntenger(begin, end, data));
case 'l':
return std::make_shared<BCode>(BCodeList(begin, end, data));
case 'd':
return std::make_shared<BCode>(BCodeDictionary(begin,end,data));
default:
return std::make_shared<BCode>(BCodeString(begin, end, data));
} } NAMESPACEEND(DEF)
BCode.cpp
测试代码
#include <iostream>
#include "MetaFIleManager.h"
#include "BCode.h"
using namespace DEF;
void BCodetest() {
std::string s = "li1234e8:12345678l3:def3:abce4:1234i56789ee";
//std::string s = "8:123456783:def2:121:a";
std::vector<char> test(s.begin(), s.end());
long long size = test.size();
long long idx0 = 0;
//while (idx0 < size) {
std::shared_ptr<BCode> p = GetBCodeObject(idx0, size, test);
//}
std::cout << std::endl << std::endl;;
std::string s1 = "d4:key1d9:innerKey14:teste9:innerkey2li23456ei1234ei45678eee";
std::vector<char> test1(s1.begin(), s1.end());
long long size1 = test1.size();
long long idx1 = 0;
std::shared_ptr<BCode> p1 = GetBCodeObject(idx1, size1, test1);
}
int main()
{
BCodetest();
}
运行效果如图:
BCode解码练习的更多相关文章
- Huffman树及其编解码
Huffman树--编解码 介绍: Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...
- linux字符串url编码与解码
编码的两种方式 echo '手机' | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g' echo '手机' |tr -d '\n' |od -An -tx ...
- URI编码解码和base64
概述 对于uri的编解码,在js中有3对函数,分别是escape/unescape,encodeURI/decodeURI,encodeURIComponent/decodeURIComponent. ...
- FFmpeg学习2:解码数据结构及函数总结
在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...
- Unicode转义(\uXXXX)的编码和解码
在涉及Web前端开发时, 有时会遇到\uXXXX格式表示的字符, 其中XXXX是16进制数字的字符串表示形式, 在js中这个叫Unicode转义字符, 和\n \r同属于转义字符. 在其他语言中也有类 ...
- C# base 64图片编码解码
使用WinForm实现了图片base64编码解码的 效果图: 示例base 64编码字符串: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKD ...
- java编码原理,java编码和解码问题
java的编码方式原理 java的JVM的缺省编码方式由系统的“本地语言环境”设置确定,和操作系统的类型无关 . 在JAVA源文件-->JAVAC-->Class-->Java--& ...
- [LeetCode] Decode String 解码字符串
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- [LeetCode] Encode and Decode Strings 加码解码字符串
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...
随机推荐
- Disconnected from the target VM, address: '127.0.0.1:57178', transport: 'socket'
idea 执行测试单元debug时控制台出现:Disconnected from the target VM, address: '127.0.0.1:57178', transport: 'sock ...
- jersey 用FastJson替换掉默认的Jackson
@Bean public ResourceConfig resourceConfig() { ResourceConfig resourceConfig = new ResourceConfig(); ...
- Mysql将查询结果合并为一列
利用函数:group_concat(),实现一个ID对应多个名称时,原本为多行数据,把名称合并成一行. 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order B ...
- 浅谈C#堆栈与托管堆的工作方式(转)
C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...
- CAtia_打开提示:许可证过期怎么办
CAtia_许可证过期怎么办:进计算机管理,点开服务和应用程序,点服务,找到DS License Server,在启动此服务的地方点启动,从而开启DS License Server.
- CString类型与其他类型的转换
1.BSTR转CString BSTR bstr; CString cstr; cstr = (LPCTSTR)bstr; 2.Cstring 转BSTR CString cstr = _T(&qu ...
- C# 异步机制
Delegate.Invoke Delegate.Invoke is used to execute a delegate on the current thread. A delegate is j ...
- Apple watch ,小米微信通知
Applewatch怎么显示微信通知?iWatch显示微信消息通知设置方法.大家都知道Applewatch上收到微信消息,iWatch是不会显示通知的,需要用户自行设置才行.下面小编来教大家如何设置A ...
- SpringCloud-day08-Hystrix断路器
8.Hystrix断路器 8.1.Hystrix简介 在分布式环境中,许多服务依赖项中的一些必然会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互. Hys ...
- Game Engine Architecture 8
[Game Engine Architecture 8] 1.Differences across Operating Systems • UNIX uses a forward slash (/) ...