mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Protobuf: Extract protobuf encoder.
This commit is contained in:
parent
a54d371549
commit
8bc7342c3c
6 changed files with 611 additions and 221 deletions
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -228,7 +228,7 @@ MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_protocol_conn" "srs_pro
|
|||
"srs_protocol_rtmp_stack" "srs_protocol_utility" "srs_protocol_rtmp_msg_array" "srs_protocol_stream"
|
||||
"srs_protocol_raw_avc" "srs_protocol_rtsp_stack" "srs_protocol_http_stack" "srs_protocol_kbps" "srs_protocol_json"
|
||||
"srs_protocol_format" "srs_protocol_log" "srs_protocol_st" "srs_protocol_http_client"
|
||||
"srs_protocol_http_conn" "srs_protocol_rtmp_conn")
|
||||
"srs_protocol_http_conn" "srs_protocol_rtmp_conn" "srs_protocol_protobuf")
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
MODULE_FILES+=("srs_protocol_srt")
|
||||
ModuleLibIncs+=(${LibSRTRoot})
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <srs_app_statistic.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_protocol_protobuf.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
@ -159,161 +160,11 @@ namespace tencentcloud_api_sign {
|
|||
}
|
||||
}
|
||||
|
||||
// See https://developers.google.com/protocol-buffers/docs/encoding#varints
|
||||
class SrsProtobufVarints
|
||||
{
|
||||
private:
|
||||
// See Go bits.Len64 of package math/bits.
|
||||
static int bits_len64(uint64_t x) {
|
||||
// See Go bits.len8tab of package math/bits.
|
||||
static uint8_t bits_len8tab[256] = {
|
||||
0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
};
|
||||
|
||||
int n = 0;
|
||||
if (x >= (uint64_t)1<<32) {
|
||||
x >>= 32;
|
||||
n = 32;
|
||||
}
|
||||
if (x >= (uint64_t)1<<16) {
|
||||
x >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (x >= (uint64_t)1<<8) {
|
||||
x >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
return n + int(bits_len8tab[x]);
|
||||
}
|
||||
public:
|
||||
// See Go protowire.SizeVarint of package google.golang.org/protobuf/encoding/protowire
|
||||
static int sizeof_varint(uint64_t v) {
|
||||
int n = bits_len64(v);
|
||||
return int(9 * uint32_t(n) + 64) / 64;
|
||||
}
|
||||
// See Go protowire.AppendVarint of package google.golang.org/protobuf/encoding/protowire
|
||||
static srs_error_t encode(SrsBuffer* b, uint64_t v) {
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!b->require(SrsProtobufVarints::sizeof_varint(v))) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require %d only %d bytes", v, b->left());
|
||||
}
|
||||
|
||||
if (v < (uint64_t)1<<7) {
|
||||
b->write_1bytes((uint8_t)v);
|
||||
} else if (v < (uint64_t)1<<14) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>7));
|
||||
} else if (v < (uint64_t)1<<21) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>21));
|
||||
} else if (v < (uint64_t)1<<35) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>28));
|
||||
} else if (v < (uint64_t)1<<42) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>35));
|
||||
} else if (v < (uint64_t)1<<49) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>42));
|
||||
} else if(v < (uint64_t)1<<56) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>49));
|
||||
} else if (v < (uint64_t)1<<63) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>49)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>56));
|
||||
} else {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>49)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>56)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)1);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
class SrsProtobufString
|
||||
{
|
||||
public:
|
||||
// See Go protowire.SizeBytes of package google.golang.org/protobuf/encoding/protowire
|
||||
static int sizeof_string(const std::string& v) {
|
||||
uint64_t n = v.length();
|
||||
return SrsProtobufVarints::sizeof_varint(uint64_t(n)) + n;
|
||||
}
|
||||
// See Go protowire.AppendString of package google.golang.org/protobuf/encoding/protowire
|
||||
static srs_error_t encode(SrsBuffer* b, const std::string& v) {
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
uint64_t n = v.length();
|
||||
if ((err = SrsProtobufVarints::encode(b, n)) != srs_success) {
|
||||
return srs_error_wrap(err, "string size %d", n);
|
||||
}
|
||||
|
||||
if (!b->require(n)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require %d only %d byte", n, b->left());
|
||||
}
|
||||
b->write_string(v);
|
||||
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
// See https://cloud.tencent.com/document/api/614/16873
|
||||
class SrsClsLogContent
|
||||
class SrsClsLogContent : public ISrsEncoder
|
||||
{
|
||||
private:
|
||||
// required string key = 1;
|
||||
std::string key_;
|
||||
// required string value = 2;
|
||||
std::string value_;
|
||||
public:
|
||||
SrsClsLogContent();
|
||||
|
@ -327,12 +178,10 @@ public:
|
|||
};
|
||||
|
||||
// See https://cloud.tencent.com/document/api/614/16873
|
||||
class SrsClsLog
|
||||
class SrsClsLog : public ISrsEncoder
|
||||
{
|
||||
private:
|
||||
// required int64 time = 1;
|
||||
int64_t time_;
|
||||
// repeated Content contents= 2;
|
||||
std::vector<SrsClsLogContent*> contents_;
|
||||
public:
|
||||
SrsClsLog();
|
||||
|
@ -346,12 +195,10 @@ public:
|
|||
};
|
||||
|
||||
// See https://cloud.tencent.com/document/api/614/16873
|
||||
class SrsClsLogGroup
|
||||
class SrsClsLogGroup : public ISrsEncoder
|
||||
{
|
||||
private:
|
||||
// repeated Log logs= 1;
|
||||
std::vector<SrsClsLog*> logs_;
|
||||
// optional string source = 4;
|
||||
std::string source_;
|
||||
public:
|
||||
SrsClsLogGroup();
|
||||
|
@ -368,7 +215,6 @@ public:
|
|||
class SrsClsLogGroupList
|
||||
{
|
||||
private:
|
||||
// repeated LogGroup logGroupList = 1;
|
||||
std::vector<SrsClsLogGroup*> groups_;
|
||||
public:
|
||||
SrsClsLogGroupList();
|
||||
|
@ -402,8 +248,8 @@ SrsClsLogContent* SrsClsLogContent::set_value(std::string v)
|
|||
|
||||
uint64_t SrsClsLogContent::nb_bytes()
|
||||
{
|
||||
uint64_t nn = 1 + SrsProtobufString::sizeof_string(key_);
|
||||
nn += 1 + SrsProtobufString::sizeof_string(value_);
|
||||
uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(key_);
|
||||
nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(value_);
|
||||
return nn;
|
||||
}
|
||||
|
||||
|
@ -411,21 +257,19 @@ srs_error_t SrsClsLogContent::encode(SrsBuffer* b)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Encode the field key as [ID=1, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
// required string key = 1;
|
||||
if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
b->write_1bytes(0x0a);
|
||||
|
||||
if ((err = SrsProtobufString::encode(b, key_)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode key=%s", key_.c_str());
|
||||
}
|
||||
|
||||
// Encode the field value as [ID=2, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
// required string value = 2;
|
||||
if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
b->write_1bytes(0x12);
|
||||
|
||||
if ((err = SrsProtobufString::encode(b, value_)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode value=%s", value_.c_str());
|
||||
|
@ -461,12 +305,11 @@ SrsClsLog* SrsClsLog::set_time(int64_t v)
|
|||
|
||||
uint64_t SrsClsLog::nb_bytes()
|
||||
{
|
||||
uint64_t nn = 1 + SrsProtobufVarints::sizeof_varint(time_);
|
||||
uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(time_);
|
||||
|
||||
for (std::vector<SrsClsLogContent*>::iterator it = contents_.begin(); it != contents_.end(); ++it) {
|
||||
SrsClsLogContent* content = *it;
|
||||
uint64_t size = content->nb_bytes();
|
||||
nn += 1 + SrsProtobufVarints::sizeof_varint(size) + size;
|
||||
nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(content);
|
||||
}
|
||||
|
||||
return nn;
|
||||
|
@ -476,11 +319,10 @@ srs_error_t SrsClsLog::encode(SrsBuffer* b)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Encode the field time as [ID=1, TYPE=0(Varint)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
// required int64 time = 1;
|
||||
if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldVarint)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
b->write_1bytes(0x08);
|
||||
|
||||
if ((err = SrsProtobufVarints::encode(b, time_)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode time");
|
||||
|
@ -490,20 +332,12 @@ srs_error_t SrsClsLog::encode(SrsBuffer* b)
|
|||
for (std::vector<SrsClsLogContent*>::iterator it = contents_.begin(); it != contents_.end(); ++it) {
|
||||
SrsClsLogContent* content = *it;
|
||||
|
||||
// Encode the field contents as [ID=2, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
}
|
||||
b->write_1bytes(0x12);
|
||||
|
||||
// Encode the varint size of children.
|
||||
uint64_t size = content->nb_bytes();
|
||||
if ((err = SrsProtobufVarints::encode(b, size)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode size=%d", (int)size);
|
||||
// repeated Content contents= 2;
|
||||
if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldObject)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
|
||||
// Encode the content itself.
|
||||
if ((err = content->encode(b)) != srs_success) {
|
||||
if ((err = SrsProtobufObject::encode(b, content)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode content");
|
||||
}
|
||||
}
|
||||
|
@ -541,11 +375,10 @@ uint64_t SrsClsLogGroup::nb_bytes()
|
|||
uint64_t nn = 0;
|
||||
for (std::vector<SrsClsLog*>::iterator it = logs_.begin(); it != logs_.end(); ++it) {
|
||||
SrsClsLog* log = *it;
|
||||
uint64_t size = log->nb_bytes();
|
||||
nn += 1 + SrsProtobufVarints::sizeof_varint(size) + size;
|
||||
nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(log);
|
||||
}
|
||||
|
||||
nn += 1 + SrsProtobufString::sizeof_string(source_);
|
||||
nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(source_);
|
||||
return nn;
|
||||
}
|
||||
|
||||
|
@ -557,29 +390,20 @@ srs_error_t SrsClsLogGroup::encode(SrsBuffer* b)
|
|||
for (std::vector<SrsClsLog*>::iterator it = logs_.begin(); it != logs_.end(); ++it) {
|
||||
SrsClsLog* log = *it;
|
||||
|
||||
// Encode the field logs as [ID=1, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
}
|
||||
b->write_1bytes(0x0a);
|
||||
|
||||
// Encode the varint size of children.
|
||||
uint64_t size = log->nb_bytes();
|
||||
if ((err = SrsProtobufVarints::encode(b, size)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode size=%d", (int)size);
|
||||
// repeated Log logs= 1;
|
||||
if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
|
||||
// Encode the log itself.
|
||||
if ((err = log->encode(b)) != srs_success) {
|
||||
if ((err = SrsProtobufObject::encode(b, log)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode log");
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the field source as [ID=4, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
// optional string source = 4;
|
||||
if ((err = SrsProtobufKey::encode(b, 4, SrsProtobufFieldString)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
b->write_1bytes(0x22);
|
||||
|
||||
if ((err = SrsProtobufString::encode(b, source_)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode source=%s", source_.c_str());
|
||||
|
@ -612,8 +436,7 @@ uint64_t SrsClsLogGroupList::nb_bytes()
|
|||
uint64_t nn = 0;
|
||||
for (std::vector<SrsClsLogGroup*>::iterator it = groups_.begin(); it != groups_.end(); ++it) {
|
||||
SrsClsLogGroup* group = *it;
|
||||
uint64_t size = group->nb_bytes();
|
||||
nn += 1 + SrsProtobufVarints::sizeof_varint(size) + size;
|
||||
nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(group);
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
|
@ -626,20 +449,12 @@ srs_error_t SrsClsLogGroupList::encode(SrsBuffer* b)
|
|||
for (std::vector<SrsClsLogGroup*>::iterator it = groups_.begin(); it != groups_.end(); ++it) {
|
||||
SrsClsLogGroup* group = *it;
|
||||
|
||||
// Encode the field groups as [ID=1, TYPE=2(Length delimited)]
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
}
|
||||
b->write_1bytes(0x0a);
|
||||
|
||||
// Encode the varint size of children.
|
||||
uint64_t size = group->nb_bytes();
|
||||
if ((err = SrsProtobufVarints::encode(b, size)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode size=%d", (int)size);
|
||||
// repeated LogGroup logGroupList = 1;
|
||||
if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldLengthDelimited)) != srs_success) {
|
||||
return srs_error_wrap(err, "key");
|
||||
}
|
||||
|
||||
// Encode the log group itself.
|
||||
if ((err = group->encode(b)) != srs_success) {
|
||||
if ((err = SrsProtobufObject::encode(b, group)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode group");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -339,6 +339,10 @@ void SrsBuffer::write_le8bytes(int64_t value)
|
|||
|
||||
void SrsBuffer::write_string(string value)
|
||||
{
|
||||
if (value.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
srs_assert(require((int)value.length()));
|
||||
|
||||
memcpy(p, value.data(), value.length());
|
||||
|
@ -347,6 +351,10 @@ void SrsBuffer::write_string(string value)
|
|||
|
||||
void SrsBuffer::write_bytes(char* data, int size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
srs_assert(require(size));
|
||||
|
||||
memcpy(p, data, size);
|
||||
|
|
210
trunk/src/protocol/srs_protocol_protobuf.cpp
Normal file
210
trunk/src/protocol/srs_protocol_protobuf.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
//
|
||||
// Copyright (c) 2013-2022 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
||||
//
|
||||
|
||||
#include <srs_protocol_protobuf.hpp>
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// See Go bits.Len64 of package math/bits.
|
||||
int SrsProtobufVarints::bits_len64(uint64_t x)
|
||||
{
|
||||
// See Go bits.len8tab of package math/bits.
|
||||
static uint8_t bits_len8tab[256] = {
|
||||
0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
};
|
||||
|
||||
int n = 0;
|
||||
if (x >= (uint64_t)1<<32) {
|
||||
x >>= 32;
|
||||
n = 32;
|
||||
}
|
||||
if (x >= (uint64_t)1<<16) {
|
||||
x >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (x >= (uint64_t)1<<8) {
|
||||
x >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
return n + int(bits_len8tab[x]);
|
||||
}
|
||||
|
||||
// See Go protowire.SizeVarint of package google.golang.org/protobuf/encoding/protowire
|
||||
int SrsProtobufVarints::sizeof_varint(uint64_t v)
|
||||
{
|
||||
int n = bits_len64(v);
|
||||
return int(9 * uint32_t(n) + 64) / 64;
|
||||
}
|
||||
|
||||
// See Go protowire.AppendVarint of package google.golang.org/protobuf/encoding/protowire
|
||||
srs_error_t SrsProtobufVarints::encode(SrsBuffer* b, uint64_t v)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!b->require(SrsProtobufVarints::sizeof_varint(v))) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require %d only %d bytes", v, b->left());
|
||||
}
|
||||
|
||||
if (v < (uint64_t)1<<7) {
|
||||
b->write_1bytes((uint8_t)v);
|
||||
} else if (v < (uint64_t)1<<14) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>7));
|
||||
} else if (v < (uint64_t)1<<21) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>14));
|
||||
} else if (v < (uint64_t)1<<28) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>21));
|
||||
} else if (v < (uint64_t)1<<35) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>28));
|
||||
} else if (v < (uint64_t)1<<42) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>35));
|
||||
} else if (v < (uint64_t)1<<49) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>42));
|
||||
} else if(v < (uint64_t)1<<56) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>49));
|
||||
} else if (v < (uint64_t)1<<63) {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>49)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(v>>56));
|
||||
} else {
|
||||
b->write_1bytes((uint8_t)(((v>>0)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>7)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>14)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>21)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>28)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>35)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>42)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>49)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)(((v>>56)&0x7f)|0x80));
|
||||
b->write_1bytes((uint8_t)1);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// See Go protowire.SizeBytes of package google.golang.org/protobuf/encoding/protowire
|
||||
int SrsProtobufString::sizeof_string(const std::string& v)
|
||||
{
|
||||
uint64_t n = v.length();
|
||||
return SrsProtobufVarints::sizeof_varint(uint64_t(n)) + n;
|
||||
}
|
||||
|
||||
// See Go protowire.AppendString of package google.golang.org/protobuf/encoding/protowire
|
||||
srs_error_t SrsProtobufString::encode(SrsBuffer* b, const std::string& v)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
uint64_t n = v.length();
|
||||
if ((err = SrsProtobufVarints::encode(b, n)) != srs_success) {
|
||||
return srs_error_wrap(err, "string size %d", n);
|
||||
}
|
||||
|
||||
// Ignore content if empty.
|
||||
if (v.empty()) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!b->require(n)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require %d only %d byte", n, b->left());
|
||||
}
|
||||
b->write_string(v);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsProtobufObject::sizeof_object(ISrsEncoder* obj)
|
||||
{
|
||||
uint64_t size = obj->nb_bytes();
|
||||
return SrsProtobufVarints::sizeof_varint(size) + size;
|
||||
}
|
||||
srs_error_t SrsProtobufObject::encode(SrsBuffer* b, ISrsEncoder* obj)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Encode the varint size of children.
|
||||
uint64_t size = obj->nb_bytes();
|
||||
if ((err = SrsProtobufVarints::encode(b, size)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode size=%d", (int)size);
|
||||
}
|
||||
|
||||
// Encode the log group itself.
|
||||
if ((err = obj->encode(b)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode group");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsProtobufKey::sizeof_key()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
srs_error_t SrsProtobufKey::encode(SrsBuffer* b, uint8_t fieldId, SrsProtobufField fieldType)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!b->require(1)) {
|
||||
return srs_error_new(ERROR_PB_NO_SPACE, "require 1 byte");
|
||||
}
|
||||
|
||||
uint8_t v = (fieldId << 3) | uint8_t(fieldType);
|
||||
b->write_1bytes(v);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
107
trunk/src/protocol/srs_protocol_protobuf.hpp
Normal file
107
trunk/src/protocol/srs_protocol_protobuf.hpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// Copyright (c) 2013-2022 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
||||
//
|
||||
|
||||
#ifndef SRS_PROTOCOL_PROTOBUF_HPP
|
||||
#define SRS_PROTOCOL_PROTOBUF_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
class SrsBuffer;
|
||||
class ISrsEncoder;
|
||||
|
||||
// See https://developers.google.com/protocol-buffers/docs/encoding#varints
|
||||
class SrsProtobufVarints
|
||||
{
|
||||
private:
|
||||
static int bits_len64(uint64_t x);
|
||||
public:
|
||||
static int sizeof_varint(uint64_t v);
|
||||
static srs_error_t encode(SrsBuffer* b, uint64_t v);
|
||||
};
|
||||
|
||||
// See https://developers.google.com/protocol-buffers/docs/encoding#strings
|
||||
class SrsProtobufString
|
||||
{
|
||||
public:
|
||||
static int sizeof_string(const std::string& v);
|
||||
static srs_error_t encode(SrsBuffer* b, const std::string& v);
|
||||
};
|
||||
|
||||
// For embeded messages and packed repeated fields, see usage of SrsProtobufKey.
|
||||
class SrsProtobufObject
|
||||
{
|
||||
public:
|
||||
static int sizeof_object(ISrsEncoder* obj);
|
||||
static srs_error_t encode(SrsBuffer* b, ISrsEncoder* obj);
|
||||
};
|
||||
|
||||
// See https://developers.google.com/protocol-buffers/docs/encoding#structure
|
||||
enum SrsProtobufField
|
||||
{
|
||||
// For int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||
SrsProtobufFieldVarint = 0,
|
||||
// For fixed64, sfixed64, double
|
||||
SrsProtobufField64bit = 1,
|
||||
// For string, bytes, embedded messages, packed repeated fields
|
||||
SrsProtobufFieldString = 2,
|
||||
SrsProtobufFieldBytes = 2,
|
||||
SrsProtobufFieldObject = 2,
|
||||
SrsProtobufFieldLengthDelimited = 2,
|
||||
// For fixed32, sfixed32, float
|
||||
SrsProtobufField32bit = 5,
|
||||
};
|
||||
|
||||
// See https://developers.google.com/protocol-buffers/docs/encoding#structure
|
||||
// See https://cloud.tencent.com/document/api/614/16873
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// If key is string, for example:
|
||||
// message Content {
|
||||
// required string value = 2;
|
||||
// }
|
||||
// We can get the size of value:
|
||||
// SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(value_)
|
||||
// And marshal as:
|
||||
// SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)
|
||||
// SrsProtobufString::encode(b, value_)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// If key is varints, for example:
|
||||
// message Log {
|
||||
// required int64 time = 1;
|
||||
// }
|
||||
// We can get the size of logs:
|
||||
// SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(time_)
|
||||
// And marshal as:
|
||||
// SrsProtobufKey::encode(b, 1, SrsProtobufFieldVarint)
|
||||
// SrsProtobufVarints::encode(b, time_)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// If key is object(or embeded message, or packed repeated fields), for example:
|
||||
// message LogGroupList {
|
||||
// repeated LogGroup logGroupList = 1;
|
||||
// }
|
||||
// We can get the size of logs:
|
||||
// for group in vector<LogGroup*>:
|
||||
// size += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(group)
|
||||
// And marshal as:
|
||||
// for group in vector<LogGroup*>:
|
||||
// SrsProtobufKey::encode(b, 1, SrsProtobufFieldLengthDelimited)
|
||||
// SrsProtobufObject::encode(b, group)
|
||||
// Note that there is always a key and length for each repeat object.
|
||||
class SrsProtobufKey
|
||||
{
|
||||
public:
|
||||
static int sizeof_key();
|
||||
// Each key in the streamed message is a varint with the value (field_number << 3) | wire_type – in other words,
|
||||
// the last three bits of the number store the wire type.
|
||||
static srs_error_t encode(SrsBuffer* b, uint8_t fieldId, SrsProtobufField fieldType);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -17,6 +17,8 @@ using namespace std;
|
|||
#include <srs_protocol_amf0.hpp>
|
||||
#include <srs_protocol_rtmp_stack.hpp>
|
||||
#include <srs_protocol_http_conn.hpp>
|
||||
#include <srs_protocol_protobuf.hpp>
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
|
||||
MockEmptyIO::MockEmptyIO()
|
||||
{
|
||||
|
@ -6455,3 +6457,251 @@ VOID TEST(ProtocolKbpsTest, WriteLargeIOVs)
|
|||
}
|
||||
}
|
||||
|
||||
VOID TEST(ProtocolProtobufTest, VarintsSize)
|
||||
{
|
||||
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x00));
|
||||
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x70));
|
||||
EXPECT_EQ(1, SrsProtobufVarints::sizeof_varint( 0x7f));
|
||||
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x80));
|
||||
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x3ff0));
|
||||
EXPECT_EQ(2, SrsProtobufVarints::sizeof_varint( 0x3fff));
|
||||
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x4000));
|
||||
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x1ffff0));
|
||||
EXPECT_EQ(3, SrsProtobufVarints::sizeof_varint( 0x1fffff));
|
||||
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x200000));
|
||||
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x0ffffff0));
|
||||
EXPECT_EQ(4, SrsProtobufVarints::sizeof_varint( 0x0fffffff));
|
||||
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x10000000));
|
||||
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x7fffffff0));
|
||||
EXPECT_EQ(5, SrsProtobufVarints::sizeof_varint( 0x7ffffffff));
|
||||
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x800000000));
|
||||
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x3fffffffff0));
|
||||
EXPECT_EQ(6, SrsProtobufVarints::sizeof_varint( 0x3ffffffffff));
|
||||
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x40000000000));
|
||||
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x1fffffffffff0));
|
||||
EXPECT_EQ(7, SrsProtobufVarints::sizeof_varint( 0x1ffffffffffff));
|
||||
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x2000000000000));
|
||||
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x0fffffffffffff0));
|
||||
EXPECT_EQ(8, SrsProtobufVarints::sizeof_varint( 0x0ffffffffffffff));
|
||||
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x100000000000000));
|
||||
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x7ffffffffffffff0));
|
||||
EXPECT_EQ(9, SrsProtobufVarints::sizeof_varint( 0x7fffffffffffffff));
|
||||
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0x8000000000000000));
|
||||
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0xfffffffffffffff0));
|
||||
EXPECT_EQ(10, SrsProtobufVarints::sizeof_varint(0xffffffffffffffff));
|
||||
}
|
||||
|
||||
VOID TEST(ProtocolProtobufTest, VarintsEncode)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
static char buf[128];
|
||||
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1); uint8_t expect[] = {0x00};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1); uint8_t expect[] = {0x70};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x70)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1); uint8_t expect[] = {0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7f)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 2); uint8_t expect[] = {0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x80)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 2); uint8_t expect[] = {0xf0, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3ff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 2); uint8_t expect[] = {0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3fff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 3); uint8_t expect[] = {0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x4000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 3); uint8_t expect[] = {0xf0, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1ffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 3); uint8_t expect[] = {0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1fffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 4); uint8_t expect[] = {0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x200000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 4); uint8_t expect[] = {0xf0, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 4); uint8_t expect[] = {0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 5); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x10000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 5); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7fffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 5); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7ffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 6); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x800000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 6); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3fffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 6); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x3ffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 7); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x40000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 7); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1fffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 7); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x1ffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 8); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x2000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 8); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 8); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 9); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x100000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 9); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7ffffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 9); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x7fffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 10); uint8_t expect[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0x8000000000000000)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 10); uint8_t expect[] = {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xfffffffffffffff0)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 10); uint8_t expect[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufVarints::encode(&b, 0xffffffffffffffff)); EXPECT_TRUE(srs_bytes_equals(buf, (char*)expect, sizeof(expect)));
|
||||
}
|
||||
}
|
||||
|
||||
VOID TEST(ProtocolProtobufTest, String)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
static char buf[128];
|
||||
|
||||
if (true) {
|
||||
EXPECT_EQ(1 + 10, SrsProtobufString::sizeof_string("HelloWorld"));
|
||||
|
||||
SrsBuffer b(buf, 1 + 10);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufString::encode(&b, "HelloWorld"));
|
||||
|
||||
uint8_t expect[] = {0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64};
|
||||
EXPECT_TRUE(srs_bytes_equals(buf, (char *) expect, sizeof(expect)));
|
||||
}
|
||||
|
||||
if (true) {
|
||||
EXPECT_EQ(1, SrsProtobufString::sizeof_string(""));
|
||||
|
||||
SrsBuffer b(buf, 1);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufString::encode(&b, ""));
|
||||
|
||||
uint8_t expect[] = {0x00};
|
||||
EXPECT_TRUE(srs_bytes_equals(buf, (char *) expect, sizeof(expect)));
|
||||
}
|
||||
}
|
||||
|
||||
class MockProtobufObject : public ISrsEncoder
|
||||
{
|
||||
public:
|
||||
uint64_t nb_bytes() {
|
||||
return 1;
|
||||
}
|
||||
srs_error_t encode(SrsBuffer* b) {
|
||||
b->write_1bytes(0x0f);
|
||||
return srs_success;
|
||||
}
|
||||
};
|
||||
|
||||
VOID TEST(ProtocolProtobufTest, FieldKey)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
static char buf[128];
|
||||
|
||||
EXPECT_EQ(2, SrsProtobufFieldString);
|
||||
EXPECT_EQ(2, SrsProtobufFieldBytes);
|
||||
EXPECT_EQ(2, SrsProtobufFieldObject);
|
||||
EXPECT_EQ(2, SrsProtobufFieldLengthDelimited);
|
||||
|
||||
EXPECT_EQ(1, SrsProtobufKey::sizeof_key());
|
||||
|
||||
MockProtobufObject obj;
|
||||
EXPECT_EQ(2, SrsProtobufObject::sizeof_object(&obj));
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 2);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufObject::encode(&b, &obj));
|
||||
EXPECT_EQ(0x01, buf[0]); EXPECT_EQ(0x0f, buf[1]);
|
||||
}
|
||||
|
||||
// Encode the field key as [ID=1, TYPE=2(Length delimited)]
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 1, SrsProtobufFieldLengthDelimited));
|
||||
EXPECT_EQ(0x0a, buf[0]);
|
||||
}
|
||||
|
||||
// Encode the field value as [ID=2, TYPE=2(Length delimited)]
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 2, SrsProtobufFieldLengthDelimited));
|
||||
EXPECT_EQ(0x12, buf[0]);
|
||||
}
|
||||
|
||||
// Encode the field time as [ID=1, TYPE=0(Varint)]
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 1, SrsProtobufFieldVarint));
|
||||
EXPECT_EQ(0x08, buf[0]);
|
||||
}
|
||||
|
||||
// Encode the field source as [ID=4, TYPE=2(Length delimited)]
|
||||
if (true) {
|
||||
SrsBuffer b(buf, 1);
|
||||
HELPER_ASSERT_SUCCESS(SrsProtobufKey::encode(&b, 4, SrsProtobufFieldLengthDelimited));
|
||||
EXPECT_EQ(0x22, buf[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue