1,外圍調用的 js方法:
win.webContents.session.getCacheData("http://192.168.50.206:8080/back.html1").then(
result=>{
console.log("getCacheData resolve:"+result);
},
result=>{
console.log("getCacheData reject:"+result);
});
});
2,調用到對應的c++綁定: D:\dev\electron7\src\electron\shell\browser\api\atom_api_session.cc
v8::Local<v8::Promise> Session::GetCacheData(mate::Arguments* args,
const std::string& url) {
auto* isolate = v8::Isolate::GetCurrent();
auto promise = util::Promise(isolate);
auto handle = promise.GetHandle();
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->ComputeHttpCacheData(
base::Time(), base::Time::Max(), url,
base::BindOnce(
[](util::Promise promise, const std::vector<int8_t>& buffer,
int64_t size_or_error) {
if (size_or_error <= 0) {
promise.RejectWithErrorMessage(
"Not Found.");
} else {
promise.Resolve(node::Buffer::Copy(v8::Isolate::GetCurrent(),
(const char*)buffer.data(),
buffer.size())
.ToLocalChecked());
}
},
std::move(promise)));
return handle;
}
3,函數裡調用的是mojo接口:D:\dev\electron7\src\services\network\public\mojom\network_context.mojom
ComputeHttpCacheData(mojo_base.mojom.Time start_time,
mojo_base.mojom.Time end_time,
string url
)
=> (array<int8> buffer, int64 size_or_error);
4,編譯時mojo自動生成的頭檔案:
void ComputeHttpCacheSize0(::base::Time start_time, ::base::Time end_time, const std::string& url, ComputeHttpCacheSize0Callback callback) final;
using ComputeHttpCacheSize0Callback = base::OnceCallback<void(const std::vector<int8_t>&, int64_t)>;
virtual void ComputeHttpCacheSize0(::base::Time start_time, ::base::Time end_time, const std::string& url, ComputeHttpCacheSize0Callback callback) = 0;
5,對mojo接口實作:D:\dev\electron7\src\services\network\network_context.cc
void NetworkContext::ComputeHttpCacheData(
base::Time start_time,
base::Time end_time,
const std::string& url,
ComputeHttpCacheDataCallback callback) { //ComputeHttpCacheDataCallback: -> base::OnceCallback<void(const std::vector<uint8_t>&, int64_t)>;
// It's safe to use Unretained below as the HttpCacheDataCounter is owned by
// |this| and guarantees it won't call its callback if deleted.
http_cache_data_counters_.push_back(HttpCacheDataCounter::CreateAndStart(
url_request_context_, start_time, end_time,url,
base::BindOnce(&NetworkContext::OnHttpCacheDataComputed,
base::Unretained(this), std::move(callback))));
}
回調OnHttpCacheDataComputed 實作:這裡的Run會回調回atom_api_session的調用
ComputeHttpCacheData(_1,_2,callback)
的第三個參數回調中。
void NetworkContext::OnHttpCacheDataComputed(
ComputeHttpCacheDataCallback callback,
HttpCacheDataCounter* counter,
const std::vector<int8_t>& buffer,
int64_t result_or_error) {
EraseIf(http_cache_data_counters_, base::MatchesUniquePtr(counter));
std::move(callback).Run(buffer, result_or_error);
}
對應頭檔案D:\dev\electron7\src\services\network\network_context.h:
void ComputeHttpCacheData(base::Time start_time,
base::Time end_time,
const std::string& url,
ComputeHttpCacheDataCallback callback) override;
void OnHttpCacheDataComputed(ComputeHttpCacheDataCallback callback,
HttpCacheDataCounter* counter,
const std::vector<int8_t>& buffer,
int64_t result_or_error);
6,mojo接口往外調用到的真正幹活類:D:\dev\electron7\src\services\network\http_cache_data_counter.h
回調
using HttpCacheDataCounterCallback0 = base::OnceCallback<void(HttpCacheDataCounter*,
const std::vector<int8_t>& buffer,
int64_t size_or_error)>;
靜态方法:
static std::unique_ptr<HttpCacheDataCounter> CreateAndStart(net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
const std::string& url,
HttpCacheDataCounterCallback0 callback);
私有化構造:
HttpCacheDataCounter(base::Time start_time,
base::Time end_time,
const std::string& url,
HttpCacheDataCounterCallback0 callback);
D:\dev\electron7\src\services\network\http_cache_data_counter.cc
靜态方法:
std::unique_ptr<HttpCacheDataCounter> HttpCacheDataCounter::CreateAndStart(
net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
const std::string& url,
HttpCacheDataCounterCallback0 callback) {
HttpCacheDataCounter* instance =
new HttpCacheDataCounter(start_time, end_time, std::move(callback));
net::HttpCache* http_cache =
url_request_context->http_transaction_factory()->GetCache();
if (!http_cache) {
// No cache, no space used. Posts a task, so it will run after the return.
instance->PostResult(false, 0);
} else {
std::unique_ptr<disk_cache::Backend*> backend =
std::make_unique<disk_cache::Backend*>();
disk_cache::Backend** backend_ptr = backend.get();
auto get_backend_callback =
base::BindRepeating(&HttpCacheDataCounter::GotBackend,
instance->GetWeakPtr(), base::Passed(&backend));
int rv = http_cache->GetBackend(backend_ptr, get_backend_callback);
if (rv != net::ERR_IO_PENDING) {
instance->GotBackend(std::make_unique<disk_cache::Backend*>(*backend_ptr),
rv);
}
}
return base::WrapUnique(instance);
}
私有化構造
HttpCacheDataCounter::HttpCacheDataCounter(
base::Time start_time,
base::Time end_time,
const std::string& url,
HttpCacheDataCounterCallback0 callback)
:
index_(0),
next_state_(STATE_NONE),
start_time_(start_time),
end_time_(end_time),
callback0_(std::move(callback))
{
std::cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXX careate" << std::endl;
}
h頭檔案:

// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_NETWORK_HTTP_CACHE_DATA_COUNTER_H_
#define SERVICES_NETWORK_HTTP_CACHE_DATA_COUNTER_H_
#include <memory>
#include <vector>
#include <utility>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/disk_cache/disk_cache.h"
namespace disk_cache {
class Backend;
}
namespace net {
class URLRequestContext;
}
namespace network {
// Helper to count data in HTTP cache.
// Export is for testing only.
class COMPONENT_EXPORT(NETWORK_SERVICE) HttpCacheDataCounter {
public:
using HttpCacheDataCounterCallback = base::OnceCallback<
void(HttpCacheDataCounter*, bool upper_bound, int64_t size_or_error)>;
// Computes the amount of disk space taken up by entries last used between
// [start_time, end_time), and return it, or error. Note that there may be
// some approximation with respect to both bytes and dates.
//
// Furthermore, if there is no efficient way of computing this information,
// a very loose upper bound (e.g. total disk space used by the cache) may be
// returned; in that case |upper_bound| will be set to true.
//
// Once complete, invokes |callback|, passing |this| and result.
//
// If either |this| or |url_request_context| get destroyed, |callback|
// will not be invoked.
static std::unique_ptr<HttpCacheDataCounter> CreateAndStart(
net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
HttpCacheDataCounterCallback callback);
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
using GetCacheDataCallback = base::OnceCallback<void(HttpCacheDataCounter*,
const std::vector<int8_t>& buffer,
int64_t size_or_error)>;
static std::unique_ptr<HttpCacheDataCounter> CreateAndStart(
net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
const std::string& url,
GetCacheDataCallback callback);
#endif
~HttpCacheDataCounter();
private:
HttpCacheDataCounter(base::Time start_time,
base::Time end_time,
HttpCacheDataCounterCallback callback);
void GotBackend(std::unique_ptr<disk_cache::Backend*> backend,
int error_code);
void PostResult(bool is_upper_limit, int64_t result_or_error);
base::WeakPtr<HttpCacheDataCounter> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
base::Time start_time_;
base::Time end_time_;
HttpCacheDataCounterCallback callback_;
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
HttpCacheDataCounter(base::Time start_time,
base::Time end_time,
const std::string& url,
GetCacheDataCallback callback);
// This will trigger the completion callback if appropriate
void PostResult0();
GetCacheDataCallback callback0_;
int index_ = 0; // 0: http header response; 1: content; 2:js compiled.
// Tricky here: if |this| gets deleted before |http_cache| gets deleted,
// GetBackend may still write things out (even though the callback will
// abort due to weak pointer), so the destination for the pointer can't be
// owned by |this|.
//
// While it can be transferred to the callback to GetBackend, that callback
// also needs to be kept alive for the duration of this method in order to
// get at the backend pointer in the synchronous result case.
// std::unique_ptr<disk_cache::Backend*> backend;
disk_cache::Backend* backend_;
scoped_refptr<net::GrowableIOBuffer> iobuffer_ = nullptr;
std::unique_ptr<std::vector<int8_t>> cacheResult_ =
std::make_unique<std::vector<int8_t>>();
disk_cache::EntryResult entryResult_;
disk_cache::Entry* cache_entry_;
std::string url_;
enum Command {
COMMAND_CACHE_SIZE,
COMMAND_CACHE_DATA,
COMMAND_CACHE_LIST,
COMMAND_CACHE_HEAD,
COMMAND_CACHE_CONTENT
};
Command cmd_;
enum State {
STATE_NONE,
STATE_GET_BACKEND,
STATE_GET_BACKEND_COMPLETE,
STATE_OPEN_NEXT_ENTRY,
STATE_OPEN_NEXT_ENTRY_COMPLETE,
STATE_OPEN_ENTRY,
STATE_OPEN_ENTRY_COMPLETE,
STATE_READ_RESPONSE,
STATE_READ_RESPONSE_COMPLETE,
STATE_READ_DATA,
STATE_READ_DATA_COMPLETE
};
State next_state_;
//Runs the state transition loop.
int DoLoop(int result);
// Each of these methods corresponds to a State value. If there is an
// argument, the value corresponds to the return of the previous state or
// corresponding callback.
// int DoGetBackend();
// int DoGetBackendComplete(int result);
// int DoOpenNextEntry();
// int DoOpenNextEntryComplete(int result);
int DoOpenEntry();
// int DoOpenEntryComplete(int result);
void OpenEntryCallback(disk_cache::EntryResult result);
int DoReadResponse();
int DoReadResponseComplete(int result);
int DoReadData();
int DoReadDataComplete(int result);
void HandleResult(int rv);
// Called to signal completion of asynchronous IO.
void OnIOComplete(int result);
void copy(const char* const p, const int& len);
#endif
base::WeakPtrFactory<HttpCacheDataCounter> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(HttpCacheDataCounter);
};
} // namespace network
#endif // SERVICES_NETWORK_HTTP_CACHE_DATA_COUNTER_H_
View Code
cc檔案源碼

// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/http_cache_data_counter.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
namespace network {
std::unique_ptr<HttpCacheDataCounter> HttpCacheDataCounter::CreateAndStart(
net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
HttpCacheDataCounterCallback callback) {
HttpCacheDataCounter* instance =
new HttpCacheDataCounter(start_time, end_time, std::move(callback));
net::HttpCache* http_cache =
url_request_context->http_transaction_factory()->GetCache();
if (!http_cache) {
// No cache, no space used. Posts a task, so it will run after the return.
instance->PostResult(false, 0);
} else {
// Tricky here: if |this| gets deleted before |http_cache| gets deleted,
// GetBackend may still write things out (even though the callback will
// abort due to weak pointer), so the destination for the pointer can't be
// owned by |this|.
//
// While it can be transferred to the callback to GetBackend, that callback
// also needs to be kept alive for the duration of this method in order to
// get at the backend pointer in the synchronous result case.
auto backend = std::make_unique<disk_cache::Backend*>();
disk_cache::Backend** backend_ptr = backend.get();
auto get_backend_callback =
base::BindRepeating(&HttpCacheDataCounter::GotBackend,
instance->GetWeakPtr(), base::Passed(&backend));
int rv = http_cache->GetBackend(backend_ptr, get_backend_callback);
if (rv != net::ERR_IO_PENDING) {
instance->GotBackend(std::make_unique<disk_cache::Backend*>(*backend_ptr),
rv);
}
}
return base::WrapUnique(instance);
}
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
std::unique_ptr<HttpCacheDataCounter> HttpCacheDataCounter::CreateAndStart(
net::URLRequestContext* url_request_context,
base::Time start_time,
base::Time end_time,
const std::string& url,
GetCacheDataCallback callback) {
HttpCacheDataCounter* instance =
new HttpCacheDataCounter(start_time, end_time, url,std::move(callback));
net::HttpCache* http_cache =
url_request_context->http_transaction_factory()->GetCache();
if (!http_cache) {
// No cache, no space used. Posts a task, so it will run after the return.
instance->PostResult(false, 0);
} else {
std::unique_ptr<disk_cache::Backend*> backend =
std::make_unique<disk_cache::Backend*>();
disk_cache::Backend** backend_ptr = backend.get();
auto get_backend_callback =
base::BindRepeating(&HttpCacheDataCounter::GotBackend,
instance->GetWeakPtr(), base::Passed(&backend));
int rv = http_cache->GetBackend(backend_ptr, get_backend_callback);
if (rv != net::ERR_IO_PENDING) {
instance->GotBackend(std::make_unique<disk_cache::Backend*>(*backend_ptr),
rv);
}
}
return base::WrapUnique(instance);
}
#endif
HttpCacheDataCounter::HttpCacheDataCounter(
base::Time start_time,
base::Time end_time,
HttpCacheDataCounterCallback callback)
: start_time_(start_time),
end_time_(end_time),
callback_(std::move(callback))
#ifdef CUST_NO_FEATURE_CACHE_DATA // zhibin:
{
}
#else
,
index_(0),
cmd_(COMMAND_CACHE_SIZE),
next_state_(STATE_NONE) {
LOG(INFO) << "XXXXXXXXXXXXXXXXXXXXXXXXXXXX careate" << std::endl;
}
HttpCacheDataCounter::HttpCacheDataCounter(
base::Time start_time,
base::Time end_time,
const std::string& url,
GetCacheDataCallback callback)
: start_time_(start_time),
end_time_(end_time),
callback0_(std::move(callback)),
index_(0),
url_(url),
cmd_(COMMAND_CACHE_DATA),
next_state_(STATE_NONE) {
LOG(INFO) << "XXXXXXXXXXXXXXXXXXXXXXXXXXXX careate" << std::endl;
}
#endif
HttpCacheDataCounter::~HttpCacheDataCounter() {
LOG(INFO) << "XXXXXXXXXXXXXXXXXXXXXXXXXXXX You got to kill me" << std::endl;
}
void HttpCacheDataCounter::GotBackend(
std::unique_ptr<disk_cache::Backend*> backend,
int error_code) {
DCHECK_LE(error_code, 0);
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
backend_ = *backend;
if (cmd_ == COMMAND_CACHE_SIZE) {
#endif
bool is_upper_limit = false;
if (error_code != net::OK) {
PostResult(is_upper_limit, error_code);
return;
}
if (!*backend) {
PostResult(is_upper_limit, 0);
return;
}
int64_t rv;
disk_cache::Backend* cache = *backend;
// Handle this here since some backends would DCHECK on this.
if (start_time_ > end_time_) {
PostResult(is_upper_limit, 0);
return;
}
if (start_time_.is_null() && end_time_.is_max()) {
rv = cache->CalculateSizeOfAllEntries(base::BindOnce(
&HttpCacheDataCounter::PostResult, GetWeakPtr(), is_upper_limit));
} else {
rv = cache->CalculateSizeOfEntriesBetween(
start_time_, end_time_,
base::BindOnce(&HttpCacheDataCounter::PostResult, GetWeakPtr(),
is_upper_limit));
if (rv == net::ERR_NOT_IMPLEMENTED) {
is_upper_limit = true;
rv = cache->CalculateSizeOfAllEntries(base::BindOnce(
&HttpCacheDataCounter::PostResult, GetWeakPtr(), is_upper_limit));
}
}
if (rv != net::ERR_IO_PENDING)
PostResult(is_upper_limit, rv);
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
} else if (cmd_ == COMMAND_CACHE_DATA) {
if (error_code != net::OK) {
PostResult0();
return;
}
if (!*backend) {
PostResult0();
return;
}
backend_ = *backend;
// Handle this here since some backends would DCHECK on this.
if (start_time_ > end_time_) {
PostResult0();
return;
}
if (start_time_.is_null() && end_time_.is_max()) {
next_state_ = STATE_OPEN_ENTRY;
DoLoop(net::OK);
} else {
// todo:
}
} else if (cmd_ == COMMAND_CACHE_LIST) {
// todo:
}
#endif
}
void HttpCacheDataCounter::PostResult(bool is_upper_limit,
int64_t result_or_error) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), this, is_upper_limit,
result_or_error));
}
#ifndef CUST_NO_FEATURE_CACHE_DATA // zhibin:
int HttpCacheDataCounter::DoLoop(int result) {
DCHECK(next_state_ != STATE_NONE);
LOG(INFO) << "======== DoLoop begin result=" << result << std::endl;
int rv = result;
do {
State state = next_state_;
next_state_ = STATE_NONE;
switch (state) {
case STATE_GET_BACKEND:
// DCHECK_EQ(net::OK, rv);
// rv = DoGetBackend();
break;
case STATE_GET_BACKEND_COMPLETE:
// rv = DoGetBackendComplete(rv);
break;
case STATE_OPEN_NEXT_ENTRY:
// DCHECK_EQ(net::OK, rv);
// rv = DoOpenNextEntry();
break;
case STATE_OPEN_NEXT_ENTRY_COMPLETE:
// rv = DoOpenNextEntryComplete(rv);
break;
case STATE_OPEN_ENTRY:
DCHECK_EQ(net::OK, rv);
rv = DoOpenEntry();
break;
case STATE_OPEN_ENTRY_COMPLETE:
// rv = DoOpenEntryComplete(rv);
break;
case STATE_READ_RESPONSE:
DCHECK_EQ(net::OK, rv);
rv = DoReadResponse();
break;
case STATE_READ_RESPONSE_COMPLETE:
rv = DoReadResponseComplete(rv);
break;
case STATE_READ_DATA:
DCHECK_EQ(net::OK, rv);
rv = DoReadData();
break;
case STATE_READ_DATA_COMPLETE:
rv = DoReadDataComplete(rv);
break;
default:
NOTREACHED() << "bad state";
rv = net::ERR_FAILED;
break;
}
} while (rv != net::ERR_IO_PENDING && next_state_ != STATE_NONE);
if (rv != net::ERR_IO_PENDING)
HandleResult(rv);
LOG(INFO) << "========DoLoop end " << std::endl;
return rv;
}
int HttpCacheDataCounter::DoOpenEntry() {
LOG(INFO) << "======== DoOpenEntry" << std::endl;
entryResult_ = backend_->OpenEntry(
url_, net::HIGHEST,
base::BindOnce(&HttpCacheDataCounter::OpenEntryCallback, GetWeakPtr()));
return net::ERR_IO_PENDING;
}
void HttpCacheDataCounter::OpenEntryCallback(disk_cache::EntryResult result) {
next_state_ = STATE_READ_RESPONSE;
LOG(INFO) << "=== OpenEntryCallback " << std::endl;
cache_entry_ = result.ReleaseEntry();
LOG(INFO) << "=== OpenEntryCallback " << cache_entry_ << std::endl;
if (!cache_entry_)
PostResult0();
else
DoLoop(net::OK);
}
int HttpCacheDataCounter::DoReadResponse() {
LOG(INFO) << "======== STATE_READ_RESPONSE begin" << std::endl;
next_state_ = STATE_READ_RESPONSE_COMPLETE;
if (iobuffer_ == nullptr) {
// init
const int kInitBufferSize = cache_entry_->GetDataSize(0);
if (kInitBufferSize < 1) {
NOTREACHED() << "cache_entry_->GetDataSize(0) return less than 1.";
return net::ERR_FAILED;
}
iobuffer_ = base::MakeRefCounted<net::GrowableIOBuffer>();
iobuffer_->SetCapacity(kInitBufferSize); // size of header
}
return cache_entry_->ReadData(
index_, iobuffer_->offset(), iobuffer_.get(),
iobuffer_->capacity() - iobuffer_->offset(),
base::BindRepeating(&HttpCacheDataCounter::OnIOComplete, GetWeakPtr()));
}
int HttpCacheDataCounter::DoReadResponseComplete(int result) {
if (result > 0) {
iobuffer_->set_offset(iobuffer_->offset() + result);
}
// http response must be returned in once call.
if (result && result == cache_entry_->GetDataSize(index_)) {
net::HttpResponseInfo response_info;
bool truncated_response_info = false;
if (!net::HttpCache::ParseResponseInfo(iobuffer_->StartOfBuffer(),
iobuffer_->offset(), &response_info,
&truncated_response_info)) {
// This can happen when reading data stored by content::CacheStorage.
std::cerr << "WARNING: Returning empty response info for key: "
<< std::endl;
return net::ERR_FAILED;
}
if (truncated_response_info) {
std::cerr << "WARNING: Truncated HTTP response." << std::endl;
return net::ERR_FAILED;
}
auto resp = net::HttpUtil::ConvertHeadersBackToHTTPResponse(
response_info.headers->raw_headers());
copy(resp.data(), resp.length());
// LOG(INFO) << resp << std::endl;
}
// enter next loop directly.
index_ = 1; // read content
next_state_ = STATE_READ_DATA;
return net::OK;
}
int HttpCacheDataCounter::DoReadData() {
next_state_ = STATE_READ_DATA_COMPLETE;
int buf_len_ = cache_entry_->GetDataSize(index_);
if (!buf_len_)
return buf_len_;
iobuffer_->SetCapacity(buf_len_); // iobuffer_->capacity() +
iobuffer_->set_offset(0);
return cache_entry_->ReadData(
index_, iobuffer_->offset(), iobuffer_.get(),
iobuffer_->capacity() - iobuffer_->offset(),
base::BindRepeating(&HttpCacheDataCounter::OnIOComplete, GetWeakPtr()));
}
int HttpCacheDataCounter::DoReadDataComplete(int result) {
LOG(INFO) << "======== DoReadDataComplete len=" << result << std::endl;
if (result > 0) {
iobuffer_->set_offset(iobuffer_->offset() + result);
}
if (iobuffer_->capacity() <= iobuffer_->offset()) {
return net::OK;
} else {
return net::ERR_FAILED;
}
}
void HttpCacheDataCounter::OnIOComplete(int rv) {
LOG(INFO) << "======== OnIOComplete len=" << rv << std::endl;
DoLoop(rv);
}
#if 0
int ViewCacheHelper::DoReadResponseComplete(int result) {
HandleResult(rv);
index_ = 0;
next_state_ = STATE_NONE;
return OK;
}
int HttpCacheDataCounter::DoOpenEntryComplete(int result) {
LOG(INFO) << "======== DoOpenEntryComplete" << std::endl;
return OK;
}
#endif
void HttpCacheDataCounter::HandleResult(int rv) {
DCHECK_NE(net::ERR_IO_PENDING, rv);
// DCHECK_NE(net::ERR_FAILED, rv);
LOG(INFO) << "======== HandleResult" << std::endl;
// LOG(INFO).write(iobuffer_->StartOfBuffer(), iobuffer_->offset());
if (cache_entry_) {
LOG(INFO) << "======== XXX cache_entry_->Close()" << std::endl;
cache_entry_->Close();
cache_entry_ = NULL;
}
if (rv == net::ERR_FAILED) {
LOG(INFO) << "Stream read error.." << std::endl;
} else if (rv == net::OK) { // suc
copy(iobuffer_->StartOfBuffer(), iobuffer_->offset());
}
PostResult0();
}
void HttpCacheDataCounter::PostResult0() {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback0_), this,
*(cacheResult_.get()), cacheResult_->size()));
}
void HttpCacheDataCounter::copy(const char* const p, const int& len) {
LOG(INFO) << "======== copy len=" << len << std::endl;
int8_t* initPtr = (int8_t*)(p);
int8_t* ptr = (int8_t*)(p);
while (ptr < initPtr + len) {
cacheResult_->push_back(*ptr);
ptr++;
}
}
#endif
} // namespace network
參考:
1,Mojo C++ System API
file:///D:/dev/electron7/src/mojo/public/cpp/system/README.md
2,Mojo C++ Bindings API
file:///D:/dev/electron7/src/mojo/public/cpp/bindings/README.md
3,Mojo
file:///D:/dev/electron7/src/mojo/README.md