Skip to content

Commit 8033384

Browse files
committed
Removed thread blocking
1 parent 97c99e9 commit 8033384

File tree

2 files changed

+88
-91
lines changed

2 files changed

+88
-91
lines changed

examples/RNFetchBlobWin/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"dependencies": {
1313
"react": "16.13.1",
1414
"react-native": "^0.63.0",
15-
"react-native-windows": "^0.63.0",
15+
"react-native-windows": "^0.64.0",
1616
"rn-fetch-blob": "^0.12.0"
1717
},
1818
"devDependencies": {

windows/RNFetchBlob/RNFetchBlob.cpp

+87-90
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ catch (const hresult_error& ex)
645645
}
646646

647647

648-
// mkdir - Implemented, not tested
648+
// mkdir
649649
void RNFetchBlob::mkdir(
650650
std::string path,
651651
winrt::Microsoft::ReactNative::ReactPromise<bool> promise) noexcept
@@ -721,7 +721,7 @@ catch (const hresult_error& ex)
721721
}
722722

723723

724-
// hash - Implemented, not tested
724+
// hash
725725
winrt::fire_and_forget RNFetchBlob::hash(
726726
std::string path,
727727
std::string algorithm,
@@ -775,7 +775,7 @@ catch (const hresult_error& ex)
775775
}
776776

777777

778-
// ls - Implemented, not tested
778+
// ls
779779
winrt::fire_and_forget RNFetchBlob::ls(
780780
std::string path,
781781
winrt::Microsoft::ReactNative::ReactPromise<std::vector<std::string>> promise) noexcept
@@ -808,7 +808,7 @@ catch (const hresult_error& ex)
808808
}
809809

810810

811-
// mv - Implemented, not tested
811+
// mv
812812
winrt::fire_and_forget RNFetchBlob::mv(
813813
std::string src, // from
814814
std::string dest, // to
@@ -844,7 +844,7 @@ winrt::fire_and_forget RNFetchBlob::mv(
844844
}
845845

846846

847-
// cp - Implemented, not tested
847+
// cp
848848
winrt::fire_and_forget RNFetchBlob::cp(
849849
std::string src, // from
850850
std::string dest, // to
@@ -876,7 +876,7 @@ catch (const hresult_error& ex)
876876
}
877877

878878

879-
// exists - Implemented, not tested
879+
// exists
880880
void RNFetchBlob::exists(
881881
std::string path,
882882
std::function<void(bool, bool)> callback) noexcept
@@ -889,7 +889,7 @@ void RNFetchBlob::exists(
889889
}
890890

891891

892-
// unlink - Implemented, not tested
892+
// unlink
893893
winrt::fire_and_forget RNFetchBlob::unlink(
894894
std::string path,
895895
std::function<void(std::string, bool)> callback) noexcept
@@ -918,7 +918,7 @@ catch (const hresult_error& ex)
918918
}
919919

920920

921-
// lstat - Implemented, not tested
921+
// lstat
922922
winrt::fire_and_forget RNFetchBlob::lstat(
923923
std::string path,
924924
std::function<void(std::string, winrt::Microsoft::ReactNative::JSValueArray&)> callback) noexcept
@@ -956,7 +956,7 @@ catch (...)
956956
}
957957

958958

959-
// stat - Implemented, not tested
959+
// stat
960960
winrt::fire_and_forget RNFetchBlob::stat(
961961
std::string path,
962962
std::function<void(std::string, winrt::Microsoft::ReactNative::JSValueObject&)> callback) noexcept
@@ -1018,7 +1018,7 @@ catch (const hresult_error& ex)
10181018
}
10191019

10201020

1021-
// df - Implemented, not tested
1021+
// df
10221022
winrt::fire_and_forget RNFetchBlob::df(
10231023
std::function<void(std::string, winrt::Microsoft::ReactNative::JSValueObject&)> callback) noexcept
10241024
try
@@ -1410,6 +1410,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
14101410
}
14111411
}
14121412

1413+
// TODO, set a timeout for cancellation
14131414
co_await m_tasks.Add(taskId, ProcessRequestAsync(taskId, filter, requestMessage, config, callback));
14141415
m_tasks.Cancel(taskId);
14151416
{
@@ -1515,111 +1516,107 @@ try
15151516
{
15161517
winrt::Windows::Web::Http::HttpClient httpClient{filter};
15171518

1518-
IAsyncOperationWithProgress async{ httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead) };
1519-
if (async.wait_for(config.timeout) == AsyncStatus::Completed) {
1520-
winrt::Windows::Web::Http::HttpResponseMessage response{async.get()};
1521-
IReference<uint64_t> contentLength{ response.Content().Headers().ContentLength() };
1519+
winrt::Windows::Web::Http::HttpResponseMessage response{ co_await httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead) };
1520+
IReference<uint64_t> contentLength{ response.Content().Headers().ContentLength() };
15221521

1523-
IOutputStream outputStream;
1522+
IOutputStream outputStream;
15241523

1525-
if (config.fileCache)
1524+
if (config.fileCache)
1525+
{
1526+
if (config.path.empty())
15261527
{
1527-
if (config.path.empty())
1528+
config.path = winrt::to_string(ApplicationData::Current().TemporaryFolder().Path()) + "\\RNFetchBlobTmp_" + taskId;
1529+
if (config.appendExt.length() > 0)
15281530
{
1529-
config.path = winrt::to_string(ApplicationData::Current().TemporaryFolder().Path()) + "\\RNFetchBlobTmp_" + taskId;
1530-
if (config.appendExt.length() > 0)
1531-
{
1532-
config.path += "." + config.appendExt;
1533-
}
1531+
config.path += "." + config.appendExt;
15341532
}
1535-
1536-
std::filesystem::path path{ config.path };
1537-
StorageFolder storageFolder{ co_await StorageFolder::GetFolderFromPathAsync(ApplicationData::Current().TemporaryFolder().Path()) };
1538-
StorageFile storageFile{ co_await storageFolder.CreateFileAsync(path.filename().wstring(), CreationCollisionOption::FailIfExists) };
1539-
IRandomAccessStream stream{ co_await storageFile.OpenAsync(FileAccessMode::ReadWrite) };
1540-
outputStream = stream.GetOutputStreamAt(0) ;
15411533
}
15421534

1543-
auto contentStream{ co_await response.Content().ReadAsInputStreamAsync() };
1544-
Buffer buffer{ 10 * 1024 };
1545-
uint64_t read{ 0 };
1546-
uint64_t totalRead{ 0 };
1535+
std::filesystem::path path{ config.path };
1536+
StorageFolder storageFolder{ co_await StorageFolder::GetFolderFromPathAsync(ApplicationData::Current().TemporaryFolder().Path()) };
1537+
StorageFile storageFile{ co_await storageFolder.CreateFileAsync(path.filename().wstring(), CreationCollisionOption::FailIfExists) };
1538+
IRandomAccessStream stream{ co_await storageFile.OpenAsync(FileAccessMode::ReadWrite) };
1539+
outputStream = stream.GetOutputStreamAt(0) ;
1540+
}
15471541

1548-
RNFetchBlobProgressConfig progressInfo;
1549-
uint64_t progressInterval{ 0 };
1542+
auto contentStream{ co_await response.Content().ReadAsInputStreamAsync() };
1543+
Buffer buffer{ 10 * 1024 };
1544+
uint64_t read{ 0 };
1545+
uint64_t totalRead{ 0 };
15501546

1551-
std::stringstream chunkStream;
1552-
std::stringstream resultOutput;
1547+
RNFetchBlobProgressConfig progressInfo;
1548+
uint64_t progressInterval{ 0 };
15531549

1554-
std::string readContents{""};
1550+
std::stringstream chunkStream;
1551+
std::stringstream resultOutput;
15551552

1556-
auto exists{ downloadProgressMap.find(taskId) };
1557-
if (exists != downloadProgressMap.end() && contentLength.Type() == PropertyType::UInt64) {
1558-
progressInfo = downloadProgressMap[taskId];
1553+
std::string readContents{""};
15591554

1560-
if (progressInfo.count > -1) {
1561-
progressInterval = contentLength.Value() / 100 * progressInfo.count;
1562-
}
1555+
auto exists{ downloadProgressMap.find(taskId) };
1556+
if (exists != downloadProgressMap.end() && contentLength.Type() == PropertyType::UInt64) {
1557+
progressInfo = downloadProgressMap[taskId];
1558+
1559+
if (progressInfo.count > -1) {
1560+
progressInterval = contentLength.Value() / 100 * progressInfo.count;
15631561
}
1562+
}
15641563

1565-
int64_t initialProgressTime{ winrt::clock::now().time_since_epoch().count() / 10000 };
1566-
int64_t currentProgressTime;
1564+
int64_t initialProgressTime{ winrt::clock::now().time_since_epoch().count() / 10000 };
1565+
int64_t currentProgressTime;
15671566

1568-
for (;;)
1569-
{
1570-
buffer.Length(0);
1571-
auto readBuffer{ co_await contentStream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None) };
1572-
//readBuffer.
1573-
readContents = winrt::to_string(CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, readBuffer));
1574-
read += readBuffer.Length();
1575-
totalRead += read;
1576-
1577-
if (readBuffer.Length() == 0)
1578-
{
1579-
break;
1580-
}
1581-
1582-
if (config.fileCache) {
1583-
co_await outputStream.WriteAsync(readBuffer);
1584-
}
1585-
else {
1586-
resultOutput << readContents;
1587-
}
1567+
for (;;)
1568+
{
1569+
buffer.Length(0);
1570+
auto readBuffer{ co_await contentStream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None) };
15881571

1589-
if (progressInfo.count > -1 || progressInfo.interval > -1) {
1590-
chunkStream << readContents;
1572+
//
1573+
read += readBuffer.Length();
1574+
totalRead += read;
15911575

1592-
currentProgressTime = winrt::clock::now().time_since_epoch().count() / 10000;
1593-
if ((currentProgressTime - initialProgressTime >= progressInfo.interval && progressInfo.interval > -1) ||
1594-
(totalRead >= progressInterval && progressInfo.count > -1)) {
1595-
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", L"RNFetchBlobProgress",
1596-
Microsoft::ReactNative::JSValueObject{
1597-
{ "taskId", taskId },
1598-
{ "written", int64_t(totalRead) },
1599-
{ "total", contentLength.Type() == PropertyType::UInt64 ?
1600-
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1601-
Microsoft::ReactNative::JSValue{nullptr} },
1602-
{ "chunk", chunkStream.str() },
1603-
});
1604-
chunkStream.clear();
1605-
initialProgressTime = winrt::clock::now().time_since_epoch().count() / 10000;
1606-
if (progressInfo.count > -1) {
1607-
read = 0;
1608-
}
1609-
}
1610-
}
1576+
if (readBuffer.Length() == 0)
1577+
{
1578+
break;
16111579
}
1612-
1580+
16131581
if (config.fileCache) {
1614-
callback("", "path", config.path);
1582+
co_await outputStream.WriteAsync(readBuffer);
16151583
}
16161584
else {
1617-
callback("", "result", resultOutput.str());
1585+
readContents = winrt::to_string(CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, readBuffer));
1586+
resultOutput << readContents;
1587+
}
1588+
1589+
if (progressInfo.count > -1 || progressInfo.interval > -1) {
1590+
chunkStream << readContents;
1591+
1592+
currentProgressTime = winrt::clock::now().time_since_epoch().count() / 10000;
1593+
if ((currentProgressTime - initialProgressTime >= progressInfo.interval && progressInfo.interval > -1) ||
1594+
(totalRead >= progressInterval && progressInfo.count > -1)) {
1595+
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", L"RNFetchBlobProgress",
1596+
Microsoft::ReactNative::JSValueObject{
1597+
{ "taskId", taskId },
1598+
{ "written", int64_t(totalRead) },
1599+
{ "total", contentLength.Type() == PropertyType::UInt64 ?
1600+
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1601+
Microsoft::ReactNative::JSValue{nullptr} },
1602+
{ "chunk", chunkStream.str() },
1603+
});
1604+
chunkStream.clear();
1605+
initialProgressTime = winrt::clock::now().time_since_epoch().count() / 10000;
1606+
if (progressInfo.count > -1) {
1607+
read = 0;
1608+
}
1609+
}
16181610
}
16191611
}
1612+
1613+
if (config.fileCache) {
1614+
callback("", "path", config.path);
1615+
}
16201616
else {
1621-
callback("RNFetchBlob request timed out", "error", "");
1617+
callback("", "result", resultOutput.str());
16221618
}
1619+
// callback("RNFetchBlob request timed out", "error", "");
16231620
}
16241621
catch (const hresult_error& ex)
16251622
{

0 commit comments

Comments
 (0)