Skip to content

Commit

Permalink
UniquePtr: Support array for unique ptr.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Jul 8, 2024
1 parent 0c84717 commit b51a19c
Show file tree
Hide file tree
Showing 22 changed files with 255 additions and 217 deletions.
5 changes: 1 addition & 4 deletions trunk/src/app/srs_app_caster_flv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,7 @@ srs_error_t SrsDynamicHttpConn::proxy(ISrsHttpResponseWriter* w, ISrsHttpMessage

output = o;
srs_trace("flv: proxy %s:%d %s to %s", ip.c_str(), port, r->uri().c_str(), output.c_str());

char* buffer = new char[SRS_HTTP_FLV_STREAM_BUFFER];
SrsAutoFreeA(char, buffer);


ISrsHttpResponseReader* rr = r->body_reader();
SrsHttpFileReader reader(rr);
SrsFlvDecoder dec;
Expand Down
9 changes: 4 additions & 5 deletions trunk/src/app/srs_app_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,19 +902,18 @@ srs_error_t SrsSslConnection::read(void* plaintext, size_t nn_plaintext, ssize_t
if (r0 == -1 && r1 == SSL_ERROR_WANT_READ) {
// TODO: Can we avoid copy?
int nn_cipher = nn_plaintext;
char* cipher = new char[nn_cipher];
SrsAutoFreeA(char, cipher);
SrsUniquePtr<char[]> cipher(new char[nn_cipher]);

// Read the cipher from SSL.
ssize_t nn = 0;
if ((err = transport->read(cipher, nn_cipher, &nn)) != srs_success) {
if ((err = transport->read(cipher.get(), nn_cipher, &nn)) != srs_success) {
return srs_error_wrap(err, "https: read");
}

int r0 = BIO_write(bio_in, cipher, nn);
int r0 = BIO_write(bio_in, cipher.get(), nn);
if (r0 <= 0) {
// TODO: 0 or -1 maybe block, use BIO_should_retry to check.
return srs_error_new(ERROR_HTTPS_READ, "BIO_write r0=%d, cipher=%p, size=%d", r0, cipher, nn);
return srs_error_new(ERROR_HTTPS_READ, "BIO_write r0=%d, cipher=%p, size=%d", r0, cipher.get(), nn);
}
continue;
}
Expand Down
19 changes: 8 additions & 11 deletions trunk/src/app/srs_app_dvr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,8 @@ srs_error_t SrsDvrFlvSegmenter::refresh_metadata()
int64_t cur = fs->tellg();

// buffer to write the size.
char* buf = new char[SrsAmf0Size::number()];
SrsAutoFreeA(char, buf);

SrsBuffer stream(buf, SrsAmf0Size::number());
SrsUniquePtr<char[]> buf(new char[SrsAmf0Size::number()]);
SrsBuffer stream(buf.get(), SrsAmf0Size::number());

// filesize to buf.
SrsUniquePtr<SrsAmf0Any> size(SrsAmf0Any::number((double)cur));
Expand All @@ -271,7 +269,7 @@ srs_error_t SrsDvrFlvSegmenter::refresh_metadata()

// update the flesize.
fs->seek2(filesize_offset);
if ((err = fs->write(buf, SrsAmf0Size::number(), NULL)) != srs_success) {
if ((err = fs->write(buf.get(), SrsAmf0Size::number(), NULL)) != srs_success) {
return srs_error_wrap(err, "update filesize");
}

Expand All @@ -285,7 +283,7 @@ srs_error_t SrsDvrFlvSegmenter::refresh_metadata()

// update the duration
fs->seek2(duration_offset);
if ((err = fs->write(buf, SrsAmf0Size::number(), NULL)) != srs_success) {
if ((err = fs->write(buf.get(), SrsAmf0Size::number(), NULL)) != srs_success) {
return srs_error_wrap(err, "update duration");
}

Expand Down Expand Up @@ -351,16 +349,15 @@ srs_error_t SrsDvrFlvSegmenter::encode_metadata(SrsSharedPtrMessage* metadata)
obj->set("duration", SrsAmf0Any::number(0));

int size = name->total_size() + obj->total_size();
char* payload = new char[size];
SrsAutoFreeA(char, payload);

SrsUniquePtr<char[]> payload(new char[size]);

// 11B flv header, 3B object EOF, 8B number value, 1B number flag.
duration_offset = fs->tellg() + size + 11 - SrsAmf0Size::object_eof() - SrsAmf0Size::number();
// 2B string flag, 8B number value, 8B string 'duration', 1B number flag
filesize_offset = duration_offset - SrsAmf0Size::utf8("duration") - SrsAmf0Size::number();

// convert metadata to bytes.
SrsBuffer buf(payload, size);
SrsBuffer buf(payload.get(), size);

if ((err = name->write(&buf)) != srs_success) {
return srs_error_wrap(err, "write name");
Expand All @@ -370,7 +367,7 @@ srs_error_t SrsDvrFlvSegmenter::encode_metadata(SrsSharedPtrMessage* metadata)
}

// to flv file.
if ((err = enc->write_metadata(18, payload, size)) != srs_success) {
if ((err = enc->write_metadata(18, payload.get(), size)) != srs_success) {
return srs_error_wrap(err, "write metadata");
}

Expand Down
17 changes: 8 additions & 9 deletions trunk/src/app/srs_app_hds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,17 +448,16 @@ srs_error_t SrsHds::flush_bootstrap()
srs_error_t err = srs_success;

int size = 1024*100;

char *start_abst = new char[1024*100];
SrsAutoFreeA(char, start_abst);


SrsUniquePtr<char[]> start_abst(new char[1024*100]);

int size_abst = 0;
char *start_asrt = NULL;
int size_asrt = 0;
char *start_afrt = NULL;
int size_afrt = 0;

SrsBuffer abst(start_abst, size);
SrsBuffer abst(start_abst.get(), size);

// @see video_file_format_spec_v10_1
// page: 46
Expand Down Expand Up @@ -553,7 +552,7 @@ srs_error_t SrsHds::flush_bootstrap()
abst.write_1bytes(1);
size_abst += 1;

start_asrt = start_abst + size_abst;
start_asrt = start_abst.get() + size_abst;

// follows by asrt
abst.write_4bytes(0);
Expand Down Expand Up @@ -621,7 +620,7 @@ srs_error_t SrsHds::flush_bootstrap()
size_abst += 1;

// follows by afrt
start_afrt = start_abst + size_abst;
start_afrt = start_abst.get() + size_abst;

abst.write_4bytes(0);
abst.write_string("afrt");
Expand Down Expand Up @@ -671,7 +670,7 @@ srs_error_t SrsHds::flush_bootstrap()

update_box(start_afrt, size_afrt);
size_abst += size_afrt;
update_box(start_abst, size_abst);
update_box(start_abst.get(), size_abst);

string path = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app + "/" + hds_req->stream +".abst";

Expand All @@ -680,7 +679,7 @@ srs_error_t SrsHds::flush_bootstrap()
return srs_error_new(ERROR_HDS_OPEN_BOOTSTRAP_FAILED, "open bootstrap file failed, path=%s", path.c_str());
}

if (write(fd, start_abst, size_abst) != size_abst) {
if (write(fd, start_abst.get(), size_abst) != size_abst) {
close(fd);
return srs_error_new(ERROR_HDS_WRITE_BOOTSTRAP_FAILED, "write bootstrap file failed, path=", path.c_str());
}
Expand Down
7 changes: 3 additions & 4 deletions trunk/src/app/srs_app_http_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,14 +434,13 @@ srs_error_t SrsHttpHooks::on_hls_notify(SrsContextId c, std::string url, SrsRequ
SrsUniquePtr<ISrsHttpMessage> msg(msg_raw);

int nb_buf = srs_min(nb_notify, SRS_HTTP_READ_BUFFER);
char* buf = new char[nb_buf];
SrsAutoFreeA(char, buf);

SrsUniquePtr<char[]> buf(new char[nb_buf]);

int nb_read = 0;
ISrsHttpResponseReader* br = msg->body_reader();
while (nb_read < nb_notify && !br->eof()) {
ssize_t nb_bytes = 0;
if ((err = br->read(buf, nb_buf, &nb_bytes)) != srs_success) {
if ((err = br->read(buf.get(), nb_buf, &nb_bytes)) != srs_success) {
break;
}
nb_read += (int)nb_bytes;
Expand Down
10 changes: 4 additions & 6 deletions trunk/src/app/srs_app_http_static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
}

// save sequence header, send later
char* sh_data = NULL;
int sh_size = 0;

if (true) {
// send sequence header
int64_t start = 0;
Expand All @@ -440,9 +438,9 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
return srs_error_new(ERROR_HTTP_REMUX_SEQUENCE_HEADER, "no sequence, size=%d", sh_size);
}
}
sh_data = new char[sh_size];
SrsAutoFreeA(char, sh_data);
if ((err = fs->read(sh_data, sh_size, NULL)) != srs_success) {

SrsUniquePtr<char[]> sh_data(new char[sh_size]);
if ((err = fs->read(sh_data.get(), sh_size, NULL)) != srs_success) {
return srs_error_wrap(err, "fs read");
}

Expand All @@ -458,7 +456,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
if ((err = w->write(flv_header, sizeof(flv_header))) != srs_success) {
return srs_error_wrap(err, "write flv header");
}
if (sh_size > 0 && (err = w->write(sh_data, sh_size)) != srs_success) {
if (sh_size > 0 && (err = w->write(sh_data.get(), sh_size)) != srs_success) {
return srs_error_wrap(err, "write sequence");
}

Expand Down
7 changes: 3 additions & 4 deletions trunk/src/app/srs_app_mpegts_udp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,12 @@ srs_error_t SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int
}
buffer->erase(buffer->length());
int nb_fbuf = fr.filesize();
char* fbuf = new char[nb_fbuf];
SrsAutoFreeA(char, fbuf);
if ((err = fr.read(fbuf, nb_fbuf, NULL)) != srs_success) {
SrsUniquePtr<char[]> fbuf(new char[nb_fbuf]);
if ((err = fr.read(fbuf.get(), nb_fbuf, NULL)) != srs_success) {
return srs_error_wrap(err, "read data");
}
fr.close();
buffer->append(fbuf, nb_fbuf);
buffer->append(fbuf.get(), nb_fbuf);
#endif

// find the sync byte of mpegts.
Expand Down
23 changes: 10 additions & 13 deletions trunk/src/app/srs_app_rtc_dtls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,12 @@ srs_error_t SrsDtlsCertificate::initialize()
// TODO: FIXME: Unused variable.
/*int r = */X509_digest(dtls_cert, EVP_sha256(), md, &n);

char* fp = new char[3 * n];
SrsAutoFreeA(char, fp);
char *p = fp;
SrsUniquePtr<char[]> fp(new char[3 * n]);
char* p = fp.get();

for (unsigned int i = 0; i < n; i++, ++p) {
int nb = snprintf(p, 3, "%02X", md[i]);
srs_assert(nb > 0 && nb < (3 * n - (p - fp)));
srs_assert(nb > 0 && nb < (3 * n - (p - fp.get())));
p += nb;

if(i < (n-1)) {
Expand All @@ -345,7 +344,7 @@ srs_error_t SrsDtlsCertificate::initialize()
}
}

fingerprint.assign(fp, strlen(fp));
fingerprint.assign(fp.get(), strlen(fp.get()));
srs_trace("fingerprint=%s", fingerprint.c_str());
}

Expand Down Expand Up @@ -985,21 +984,19 @@ srs_error_t SrsSRTP::initialize(string recv_key, std::string send_key)

// init recv context
policy.ssrc.type = ssrc_any_inbound;
uint8_t *rkey = new uint8_t[recv_key.size()];
SrsAutoFreeA(uint8_t, rkey);
memcpy(rkey, recv_key.data(), recv_key.size());
policy.key = rkey;
SrsUniquePtr<uint8_t[]> rkey(new uint8_t[recv_key.size()]);
memcpy(rkey.get(), recv_key.data(), recv_key.size());
policy.key = rkey.get();

srtp_err_status_t r0 = srtp_err_status_ok;
if ((r0 = srtp_create(&recv_ctx_, &policy)) != srtp_err_status_ok) {
return srs_error_new(ERROR_RTC_SRTP_INIT, "srtp create r0=%u", r0);
}

policy.ssrc.type = ssrc_any_outbound;
uint8_t *skey = new uint8_t[send_key.size()];
SrsAutoFreeA(uint8_t, skey);
memcpy(skey, send_key.data(), send_key.size());
policy.key = skey;
SrsUniquePtr<uint8_t[]> skey(new uint8_t[send_key.size()]);
memcpy(skey.get(), send_key.data(), send_key.size());
policy.key = skey.get();

if ((r0 = srtp_create(&send_ctx_, &policy)) != srtp_err_status_ok) {
return srs_error_new(ERROR_RTC_SRTP_INIT, "srtp create r0=%u", r0);
Expand Down
18 changes: 8 additions & 10 deletions trunk/src/app/srs_app_tencentcloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,16 +726,15 @@ srs_error_t SrsClsClient::do_send_logs(ISrsEncoder* sugar, int count, int total)
return srs_error_new(ERROR_CLS_EXCEED_SIZE, "exceed 5MB actual %d", size);
}

char* buf = new char[size];
SrsAutoFreeA(char, buf);
SrsUniquePtr<char[]> buf(new char[size]);

memset(buf, 0, size);
SrsBuffer b(buf, size);
memset(buf.get(), 0, size);
SrsBuffer b(buf.get(), size);
if ((err = sugar->encode(&b)) != srs_success) {
return srs_error_wrap(err, "encode log");
}

string body(buf, size);
string body(buf.get(), size);

// Write a CLS log to service specified by url.
string url = "http://" + endpoint_ + ":80/structuredlog?topic_id=" + topic_;
Expand Down Expand Up @@ -2166,16 +2165,15 @@ srs_error_t SrsApmClient::do_report()
return srs_error_new(ERROR_APM_EXCEED_SIZE, "exceed 5MB actual %d", size);
}

char* buf = new char[size];
SrsAutoFreeA(char, buf);
SrsUniquePtr<char[]> buf(new char[size]);

memset(buf, 0, size);
SrsBuffer b(buf, size);
memset(buf.get(), 0, size);
SrsBuffer b(buf.get(), size);
if ((err = sugar->encode(&b)) != srs_success) {
return srs_error_wrap(err, "encode log");
}

string body(buf, size);
string body(buf.get(), size);

// Write a CLS log to service specified by url.
string url = "http://" + endpoint_ + "/v1/traces";
Expand Down
49 changes: 49 additions & 0 deletions trunk/src/core/srs_core_autofree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,55 @@ class SrsUniquePtr
#endif
};

// The unique ptr for array objects, only support unique ptr, with limited APIs and features,
// see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
//
// Usage:
// SrsUniquePtr<MyClass[]> ptr(new MyClass[10]);
// ptr[0]->do_something();
template<class T>
class SrsUniquePtr<T[]>
{
private:
T* ptr_;
public:
SrsUniquePtr(T* ptr = NULL) {
ptr_ = ptr;
}
virtual ~SrsUniquePtr() {
delete[] ptr_;
}
public:
// Get the object.
T* get() {
return ptr_;
}
// Overload the [] operator.
T& operator[](std::size_t index) {
return ptr_[index];
}
const T& operator[](std::size_t index) const {
return ptr_[index];
}
private:
// Copy the unique ptr.
SrsUniquePtr(const SrsUniquePtr<T>&) = delete;
// The assign operator.
SrsUniquePtr<T>& operator=(const SrsUniquePtr<T>&) = delete;
private:
// Overload the * operator.
T& operator*() = delete;
// Overload the bool operator.
operator bool() const = delete;
#if __cplusplus >= 201103L // C++11
private:
// The move constructor.
SrsUniquePtr(SrsUniquePtr<T>&&) = delete;
// The move assign operator.
SrsUniquePtr<T>& operator=(SrsUniquePtr<T>&&) = delete;
#endif
};

// Shared ptr smart pointer, only support shared ptr, no weak ptr, no shared from this, no inheritance,
// no comparing, see https://github.com/ossrs/srs/discussions/3667#discussioncomment-8969107
//
Expand Down
Loading

0 comments on commit b51a19c

Please sign in to comment.