2121
2222napi_threadsafe_function g_fetch_data_threadsafe_callback = nullptr ;
2323
24- #define CHUNK_SIZE (32 * 1024 * 1024 )
25-
2624#define FIELD_SIZE (type, field ) (sizeof (((type *)0 )->field))
2725
2826#define CF_SIZE_OF_OP_PARAM (field ) \
@@ -60,70 +58,19 @@ HRESULT transfer_data(
6058 return CfExecute (&opInfo, &opParams);
6159}
6260
63- size_t file_incremental_reading (napi_env env, TransferContext &ctx)
64- {
65- std::ifstream file (ctx.tmpPath , std::ios::in | std::ios::binary);
66-
67- if (!file.is_open ())
68- {
69- throw std::runtime_error (" Failed to open tmp file" );
70- }
71-
72- file.seekg (0 , std::ios::end);
73- size_t newSize = static_cast <size_t >(file.tellg ());
74- size_t datasizeAvailableUnread = newSize - ctx.lastReadOffset ;
75-
76- if (datasizeAvailableUnread > 0 )
77- {
78- std::vector<char > buffer (CHUNK_SIZE);
79- file.seekg (ctx.lastReadOffset );
80- file.read (buffer.data (), CHUNK_SIZE);
81-
82- LARGE_INTEGER startingOffset, chunkBufferSize;
83- startingOffset.QuadPart = ctx.lastReadOffset ;
84- chunkBufferSize.QuadPart = min (datasizeAvailableUnread, CHUNK_SIZE);
85-
86- HRESULT hr = transfer_data (
87- ctx.connectionKey ,
88- ctx.transferKey ,
89- buffer.data (),
90- startingOffset,
91- chunkBufferSize,
92- STATUS_SUCCESS);
93-
94- if (FAILED (hr))
95- {
96- transfer_data (
97- ctx.connectionKey ,
98- ctx.transferKey ,
99- nullptr ,
100- ctx.requiredOffset ,
101- ctx.requiredLength ,
102- STATUS_UNSUCCESSFUL);
103-
104- winrt::throw_hresult (hr);
105- }
106-
107- ctx.lastReadOffset += chunkBufferSize.QuadPart ;
108-
109- UINT64 totalSize = static_cast <UINT64>(ctx.fileSize .QuadPart );
110- Utilities::ApplyTransferStateToFile (ctx.path , ctx.callbackInfo , totalSize, ctx.lastReadOffset );
111- }
112-
113- ctx.lastSize = newSize;
114- return ctx.lastReadOffset ;
115- }
116-
11761napi_value response_callback_fn_fetch_data (napi_env env, napi_callback_info info)
11862{
11963 wprintf (L" Function response_callback_fn_fetch_data called\n " );
12064
121- auto [response, tmpPath] = napi_extract_args< bool , std::wstring>(env, info) ;
122-
65+ size_t argc = 3 ;
66+ napi_value args[ 3 ];
12367 TransferContext *ctx = nullptr ;
124- napi_get_cb_info (env, info, nullptr , nullptr , nullptr , reinterpret_cast <void **>(&ctx));
68+ napi_get_cb_info (env, info, &argc, args , nullptr , reinterpret_cast <void **>(&ctx));
12569
126- if (!response)
70+ bool finished;
71+ napi_get_value_bool (env, args[0 ], &finished);
72+
73+ if (finished)
12774 {
12875 wprintf (L" Canceling hydration\n " );
12976
@@ -137,34 +84,57 @@ napi_value response_callback_fn_fetch_data(napi_env env, napi_callback_info info
13784 return create_response (env, true );
13885 }
13986
140- wprintf (L" Download tmp path: %s\n " , tmpPath.c_str ());
87+ void *data;
88+ size_t length;
89+ napi_get_buffer_info (env, args[1 ], &data, &length);
90+
91+ int64_t offset;
92+ napi_get_value_int64 (env, args[2 ], &offset);
14193
142- ctx->tmpPath = tmpPath;
94+ LARGE_INTEGER startingOffset, chunkSize;
95+ startingOffset.QuadPart = offset;
96+ chunkSize.QuadPart = length;
14397
144- ctx->lastReadOffset = file_incremental_reading (env, *ctx);
98+ HRESULT hr = transfer_data (
99+ ctx->connectionKey ,
100+ ctx->transferKey ,
101+ data,
102+ startingOffset,
103+ chunkSize,
104+ STATUS_SUCCESS);
145105
146- if (ctx-> lastReadOffset == ( size_t )ctx-> fileSize . QuadPart )
106+ if (FAILED (hr) )
147107 {
148- ctx->lastReadOffset = 0 ;
149- ctx->loadFinished = true ;
108+ transfer_data (
109+ ctx->connectionKey ,
110+ ctx->transferKey ,
111+ nullptr ,
112+ ctx->requiredOffset ,
113+ ctx->requiredLength ,
114+ STATUS_UNSUCCESSFUL);
115+
116+ winrt::throw_hresult (hr);
117+ }
150118
151- Utilities::ApplyTransferStateToFile ( ctx->path , ctx-> callbackInfo , ctx-> fileSize . QuadPart , ctx-> fileSize . QuadPart ) ;
119+ ctx->lastReadOffset = offset + length ;
152120
153- CfSetPinState ( handleForPath ( ctx->path . c_str ()). get (), CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr );
154- }
121+ UINT64 totalSize = static_cast <UINT64>( ctx->fileSize . QuadPart );
122+ Utilities::ApplyTransferStateToFile (ctx-> path , ctx-> callbackInfo , totalSize, ctx-> lastReadOffset );
155123
124+ if (finished)
156125 {
126+ ctx->loadFinished = true ;
127+ Utilities::ApplyTransferStateToFile (ctx->path , ctx->callbackInfo , ctx->fileSize .QuadPart , ctx->fileSize .QuadPart );
128+ CfSetPinState (handleForPath (ctx->path .c_str ()).get (), CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr );
129+
157130 std::lock_guard<std::mutex> lock (ctx->mtx );
158- if (ctx->loadFinished )
159- {
160- ctx->ready = true ;
161- ctx->cv .notify_one ();
162- }
131+ ctx->ready = true ;
132+ ctx->cv .notify_one ();
163133 }
164134
165- wprintf (L" Fetch data finished: %d\n " , ctx-> loadFinished );
135+ wprintf (L" Chunk transferred, finished: %d\n " , finished );
166136
167- return create_response (env, ctx-> loadFinished );
137+ return create_response (env, finished );
168138}
169139
170140napi_value response_callback_fn_fetch_data_wrapper (napi_env env, napi_callback_info info)
@@ -207,8 +177,6 @@ void CALLBACK fetch_data_callback_wrapper(_In_ CONST CF_CALLBACK_INFO *callbackI
207177 ctx->callbackInfo = *callbackInfo;
208178 ctx->path = std::wstring (callbackInfo->VolumeDosName ) + callbackInfo->NormalizedPath ;
209179
210- wprintf (L" Download path: %s\n " , ctx->path .c_str ());
211-
212180 napi_call_threadsafe_function (g_fetch_data_threadsafe_callback, ctx.get (), napi_tsfn_blocking);
213181
214182 {
0 commit comments