| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "stdafx.h"
- #include <sys/stat.h>
- #define MAX_URI_LENGTH 512
- //TODO: x-plat definitions
- #ifdef _WIN32
- #define TTD_MAX_FILE_LENGTH MAX_PATH
- #define TTD_HOST_PATH_SEP "\\"
- #else
- #define TTD_MAX_FILE_LENGTH MAX_URI_LENGTH
- #define TTD_HOST_PATH_SEP "/"
- #endif
- void TTDHostBuildCurrentExeDirectory(char* path, size_t* pathLength, size_t bufferLength)
- {
- char exePath[TTD_MAX_FILE_LENGTH];
- PlatformAgnostic::SystemInfo::GetBinaryLocation(exePath, TTD_MAX_FILE_LENGTH);
- size_t i = strlen(exePath) - 1;
- while (exePath[i] != TTD_HOST_PATH_SEP[0] && i != 0)
- {
- --i;
- }
- if (i == 0)
- {
- fwprintf(stderr, _u("Can't get current exe directory"));
- exit(1);
- }
- if (i + 2 > bufferLength)
- {
- fwprintf(stderr, _u("Don't overflow path buffer during copy"));
- exit(1);
- }
- memcpy_s(path, bufferLength, exePath, i + 1);
- *pathLength = i + 1;
- path[*pathLength] = '\0';
- }
- #ifdef _WIN32
- int TTDHostMKDir(const char* path, size_t pathLength)
- {
- char16 cpath[MAX_PATH];
- LPCUTF8 pathbase = (LPCUTF8)path;
- if(MAX_PATH <= pathLength) //<= to account for null terminator
- {
- wprintf(_u("Don't overflow path buffer during conversion"));
- exit(1);
- }
- utf8::DecodeUnitsIntoAndNullTerminate(cpath, pathbase, pathbase + pathLength);
- return _wmkdir(cpath);
- }
- JsTTDStreamHandle TTDHostOpen(size_t pathLength, const char* path, bool isWrite)
- {
- char16 wpath[MAX_PATH];
- LPCUTF8 pathbase = (LPCUTF8)path;
- if(MAX_PATH <= pathLength) //<= to account for null terminator
- {
- wprintf(_u("Don't overflow path buffer during conversion"));
- exit(1);
- }
- utf8::DecodeUnitsIntoAndNullTerminate(wpath, pathbase, pathbase + pathLength);
- FILE* res = nullptr;
- _wfopen_s(&res, wpath, isWrite ? _u("w+b") : _u("r+b"));
- return (JsTTDStreamHandle)res;
- }
- #define TTDHostRead(buff, size, handle) fread_s(buff, size, 1, size, (FILE*)handle);
- #define TTDHostWrite(buff, size, handle) fwrite(buff, 1, size, (FILE*)handle)
- #else
- int TTDHostMKDir(const char* path, size_t pathLength)
- {
- return mkdir(path, 0700);
- }
- JsTTDStreamHandle TTDHostOpen(size_t pathLength, const char* path, bool isWrite)
- {
- return (JsTTDStreamHandle)fopen(path, isWrite ? "w+b" : "r+b");
- }
- #define TTDHostRead(buff, size, handle) fread(buff, 1, size, (FILE*)handle)
- #define TTDHostWrite(buff, size, handle) fwrite(buff, 1, size, (FILE*)handle)
- #endif
- int GetPathNameLocation(LPCSTR filename)
- {
- int filenameLength = (int) strlen(filename);
- int pos;
- if (filenameLength <= 0)
- {
- return -1;
- }
- for (pos = filenameLength - 1; pos >= 0; pos--)
- {
- char ch = filename[pos];
- if (ch == '/' || ch == '\\') break;
- }
- return pos;
- }
- inline void pathcpy(char * target, LPCSTR src, uint length)
- {
- #ifndef _WIN32
- for (int i = 0; i < length; i++)
- {
- if (src[i] == '\\')
- {
- target[i] = '/';
- }
- else
- {
- target[i] = src[i];
- }
- }
- #else
- memcpy(target, src, length);
- #endif
- }
- uint ConcatPath(LPCSTR filenameLeft, uint posPathSep, LPCSTR filenameRight, char* buffer, uint bufferLength)
- {
- int filenameRightLength = (int) strlen(filenameRight);
- // [ path[/] ] + [filename] + /0
- uint totalLength = posPathSep + filenameRightLength + 1;
- if (buffer == nullptr)
- {
- return totalLength;
- }
- if (bufferLength < totalLength)
- {
- fprintf(stderr, "Error: file path is too long.\n");
- return (uint)-1;
- }
- pathcpy(buffer, filenameLeft, posPathSep);
- buffer += posPathSep;
- pathcpy(buffer, filenameRight, filenameRightLength);
- buffer += filenameRightLength;
- buffer[0] = char(0);
- return totalLength;
- }
- HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/)
- {
- static char sHostApplicationPathBuffer[MAX_URI_LENGTH];
- static uint sHostApplicationPathBufferLength = (uint) -1;
- char combinedPathBuffer[MAX_URI_LENGTH];
- HRESULT hr = S_OK;
- BYTE * pRawBytes = nullptr;
- BYTE * pRawBytesFromMap = nullptr;
- UINT lengthBytes = 0;
- contents = nullptr;
- FILE * file = NULL;
- size_t bufferLength = 0;
- LPCSTR filename = filenameToLoad;
- if (sHostApplicationPathBufferLength == (uint)-1)
- {
- // consider incoming filename as the host app and base its' path for others
- sHostApplicationPathBufferLength = GetPathNameLocation(filename);
- if (sHostApplicationPathBufferLength == -1)
- {
- // host app has no path info. (it must be located on current folder!)
- sHostApplicationPathBufferLength = 0;
- }
- else
- {
- sHostApplicationPathBufferLength += 1;
- Assert(sHostApplicationPathBufferLength < MAX_URI_LENGTH);
- // save host app's path and fix the path separator for platform
- pathcpy(sHostApplicationPathBuffer, filename, sHostApplicationPathBufferLength);
- }
- sHostApplicationPathBuffer[sHostApplicationPathBufferLength] = char(0);
- }
- else if (filename[0] != '/' && filename[0] != '\\') // make sure it's not a full path
- {
- // concat host path and filename
- uint len = ConcatPath(sHostApplicationPathBuffer, sHostApplicationPathBufferLength,
- filename, combinedPathBuffer, MAX_URI_LENGTH);
- if (len == (uint)-1)
- {
- hr = E_FAIL;
- goto Error;
- }
- filename = combinedPathBuffer;
- }
- // check if have it registered
- AutoString *data;
- if (SourceMap::Find(filenameToLoad, strlen(filenameToLoad), &data) ||
- SourceMap::Find(filename, strlen(filename), &data))
- {
- pRawBytesFromMap = (BYTE*) data->GetString();
- lengthBytes = (UINT) data->GetLength();
- }
- else
- {
- // Open the file as a binary file to prevent CRT from handling encoding, line-break conversions,
- // etc.
- if (fopen_s(&file, filename, "rb") != 0)
- {
- if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
- {
- #ifdef _WIN32
- DWORD lastError = GetLastError();
- char16 wszBuff[MAX_URI_LENGTH];
- fprintf(stderr, "Error in opening file '%s' ", filename);
- wszBuff[0] = 0;
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
- lastError,
- 0,
- wszBuff,
- _countof(wszBuff),
- nullptr))
- {
- fwprintf(stderr, _u(": %s"), wszBuff);
- }
- fwprintf(stderr, _u("\n"));
- #elif defined(_POSIX_VERSION)
- fprintf(stderr, "Error in opening file: ");
- perror(filename);
- #endif
- }
- IfFailGo(E_FAIL);
- }
- }
- if (file != NULL)
- {
- // Determine the file length, in bytes.
- fseek(file, 0, SEEK_END);
- lengthBytes = ftell(file);
- fseek(file, 0, SEEK_SET);
- }
- if (lengthBytes != 0)
- {
- bufferLength = lengthBytes + sizeof(BYTE);
- pRawBytes = (LPBYTE)malloc(bufferLength);
- }
- else
- {
- bufferLength = 1;
- pRawBytes = (LPBYTE)malloc(bufferLength);
- }
- if (nullptr == pRawBytes)
- {
- fwprintf(stderr, _u("out of memory"));
- IfFailGo(E_OUTOFMEMORY);
- }
- if (lengthBytes != 0)
- {
- if (file != NULL)
- {
- //
- // Read the entire content as a binary block.
- //
- size_t readBytes = fread(pRawBytes, sizeof(BYTE), lengthBytes, file);
- if (readBytes < lengthBytes * sizeof(BYTE))
- {
- IfFailGo(E_FAIL);
- }
- }
- else // from module source register
- {
- // Q: module source is on persistent memory. Why do we use the copy instead?
- // A: if we use the same memory twice, ch doesn't know that during FinalizeCallback free.
- // the copy memory will be freed by the finalizer
- Assert(pRawBytesFromMap);
- memcpy_s(pRawBytes, bufferLength, pRawBytesFromMap, lengthBytes);
- }
- }
- if (pRawBytes)
- {
- pRawBytes[lengthBytes] = 0; // Null terminate it. Could be UTF16
- }
- if (file != NULL)
- {
- //
- // Read encoding to make sure it's supported
- //
- // Warning: The UNICODE buffer for parsing is supposed to be provided by the host.
- // This is not a complete read of the encoding. Some encodings like UTF7, UTF1, EBCDIC, SCSU, BOCU could be
- // wrongly classified as ANSI
- //
- #pragma warning(push)
- // suppressing prefast warning that "readable size is bufferLength
- // bytes but 2 may be read" as bufferLength is clearly > 2 in the code that follows
- #pragma warning(disable:6385)
- C_ASSERT(sizeof(WCHAR) == 2);
- if (bufferLength > 2)
- {
- __analysis_assume(bufferLength > 2);
- #pragma prefast(push)
- #pragma prefast(disable:6385, "PREfast incorrectly reports this as an out-of-bound access.");
- if ((pRawBytes[0] == 0xFE && pRawBytes[1] == 0xFF) ||
- (pRawBytes[0] == 0xFF && pRawBytes[1] == 0xFE) ||
- (bufferLength > 4 && pRawBytes[0] == 0x00 && pRawBytes[1] == 0x00 &&
- ((pRawBytes[2] == 0xFE && pRawBytes[3] == 0xFF) ||
- (pRawBytes[2] == 0xFF && pRawBytes[3] == 0xFE))))
- {
- // unicode unsupported
- fwprintf(stderr, _u("unsupported file encoding. Only ANSI and UTF8 supported"));
- IfFailGo(E_UNEXPECTED);
- }
- #pragma prefast(pop)
- }
- #pragma warning(pop)
- }
- contents = reinterpret_cast<LPCSTR>(pRawBytes);
- Error:
- if (SUCCEEDED(hr))
- {
- if (lengthBytesOut)
- {
- *lengthBytesOut = lengthBytes;
- }
- }
- if (file != NULL)
- {
- fclose(file);
- }
- if (pRawBytes && reinterpret_cast<LPCSTR>(pRawBytes) != contents)
- {
- free(pRawBytes);
- }
- return hr;
- }
- LPCWSTR Helpers::JsErrorCodeToString(JsErrorCode jsErrorCode)
- {
- bool hasException = false;
- ChakraRTInterface::JsHasException(&hasException);
- if (hasException)
- {
- WScriptJsrt::PrintException("", JsErrorScriptException);
- }
- switch (jsErrorCode)
- {
- case JsNoError: return _u("JsNoError");
- // JsErrorCategoryUsage
- case JsErrorCategoryUsage: return _u("JsErrorCategoryUsage");
- case JsErrorInvalidArgument: return _u("JsErrorInvalidArgument");
- case JsErrorNullArgument: return _u("JsErrorNullArgument");
- case JsErrorNoCurrentContext: return _u("JsErrorNoCurrentContext");
- case JsErrorInExceptionState: return _u("JsErrorInExceptionState");
- case JsErrorNotImplemented: return _u("JsErrorNotImplemented");
- case JsErrorWrongThread: return _u("JsErrorWrongThread");
- case JsErrorRuntimeInUse: return _u("JsErrorRuntimeInUse");
- case JsErrorBadSerializedScript: return _u("JsErrorBadSerializedScript");
- case JsErrorInDisabledState: return _u("JsErrorInDisabledState");
- case JsErrorCannotDisableExecution: return _u("JsErrorCannotDisableExecution");
- case JsErrorHeapEnumInProgress: return _u("JsErrorHeapEnumInProgress");
- case JsErrorArgumentNotObject: return _u("JsErrorArgumentNotObject");
- case JsErrorInProfileCallback: return _u("JsErrorInProfileCallback");
- case JsErrorInThreadServiceCallback: return _u("JsErrorInThreadServiceCallback");
- case JsErrorCannotSerializeDebugScript: return _u("JsErrorCannotSerializeDebugScript");
- case JsErrorAlreadyDebuggingContext: return _u("JsErrorAlreadyDebuggingContext");
- case JsErrorAlreadyProfilingContext: return _u("JsErrorAlreadyProfilingContext");
- case JsErrorIdleNotEnabled: return _u("JsErrorIdleNotEnabled");
- case JsCannotSetProjectionEnqueueCallback: return _u("JsCannotSetProjectionEnqueueCallback");
- case JsErrorCannotStartProjection: return _u("JsErrorCannotStartProjection");
- case JsErrorInObjectBeforeCollectCallback: return _u("JsErrorInObjectBeforeCollectCallback");
- case JsErrorObjectNotInspectable: return _u("JsErrorObjectNotInspectable");
- case JsErrorPropertyNotSymbol: return _u("JsErrorPropertyNotSymbol");
- case JsErrorPropertyNotString: return _u("JsErrorPropertyNotString");
- case JsErrorInvalidContext: return _u("JsErrorInvalidContext");
- case JsInvalidModuleHostInfoKind: return _u("JsInvalidModuleHostInfoKind");
- case JsErrorModuleParsed: return _u("JsErrorModuleParsed");
- // JsErrorCategoryEngine
- case JsErrorCategoryEngine: return _u("JsErrorCategoryEngine");
- case JsErrorOutOfMemory: return _u("JsErrorOutOfMemory");
- case JsErrorBadFPUState: return _u("JsErrorBadFPUState");
- // JsErrorCategoryScript
- case JsErrorCategoryScript: return _u("JsErrorCategoryScript");
- case JsErrorScriptException: return _u("JsErrorScriptException");
- case JsErrorScriptCompile: return _u("JsErrorScriptCompile");
- case JsErrorScriptTerminated: return _u("JsErrorScriptTerminated");
- case JsErrorScriptEvalDisabled: return _u("JsErrorScriptEvalDisabled");
- // JsErrorCategoryFatal
- case JsErrorCategoryFatal: return _u("JsErrorCategoryFatal");
- case JsErrorFatal: return _u("JsErrorFatal");
- case JsErrorWrongRuntime: return _u("JsErrorWrongRuntime");
- // JsErrorCategoryDiagError
- case JsErrorCategoryDiagError: return _u("JsErrorCategoryDiagError");
- case JsErrorDiagAlreadyInDebugMode: return _u("JsErrorDiagAlreadyInDebugMode");
- case JsErrorDiagNotInDebugMode: return _u("JsErrorDiagNotInDebugMode");
- case JsErrorDiagNotAtBreak: return _u("JsErrorDiagNotAtBreak");
- case JsErrorDiagInvalidHandle: return _u("JsErrorDiagInvalidHandle");
- case JsErrorDiagObjectNotFound: return _u("JsErrorDiagObjectNotFound");
- case JsErrorDiagUnableToPerformAction: return _u("JsErrorDiagUnableToPerformAction");
- default:
- return _u("<unknown>");
- break;
- }
- }
- void Helpers::LogError(__in __nullterminated const char16 *msg, ...)
- {
- va_list args;
- va_start(args, msg);
- wprintf(_u("ERROR: "));
- vfwprintf(stderr, msg, args);
- wprintf(_u("\n"));
- fflush(stdout);
- va_end(args);
- }
- HRESULT Helpers::LoadBinaryFile(LPCSTR filename, LPCSTR& contents, UINT& lengthBytes, bool printFileOpenError)
- {
- HRESULT hr = S_OK;
- contents = nullptr;
- lengthBytes = 0;
- size_t result;
- FILE * file;
- //
- // Open the file as a binary file to prevent CRT from handling encoding, line-break conversions,
- // etc.
- //
- if (fopen_s(&file, filename, "rb") != 0)
- {
- if (printFileOpenError)
- {
- fprintf(stderr, "Error in opening file '%s' ", filename);
- #ifdef _WIN32
- DWORD lastError = GetLastError();
- char16 wszBuff[MAX_URI_LENGTH];
- wszBuff[0] = 0;
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
- lastError,
- 0,
- wszBuff,
- _countof(wszBuff),
- nullptr))
- {
- fwprintf(stderr, _u(": %s"), wszBuff);
- }
- #endif
- fprintf(stderr, "\n");
- }
- return E_FAIL;
- }
- // file will not be nullptr if _wfopen_s succeeds
- __analysis_assume(file != nullptr);
- //
- // Determine the file length, in bytes.
- //
- fseek(file, 0, SEEK_END);
- lengthBytes = ftell(file);
- fseek(file, 0, SEEK_SET);
- contents = (LPCSTR)HeapAlloc(GetProcessHeap(), 0, lengthBytes);
- if (nullptr == contents)
- {
- fwprintf(stderr, _u("out of memory"));
- IfFailGo(E_OUTOFMEMORY);
- }
- //
- // Read the entire content as a binary block.
- //
- result = fread((void*)contents, sizeof(char), lengthBytes, file);
- if (result != lengthBytes)
- {
- fwprintf(stderr, _u("Read error"));
- IfFailGo(E_FAIL);
- }
- Error:
- fclose(file);
- if (contents && FAILED(hr))
- {
- HeapFree(GetProcessHeap(), 0, (void*)contents);
- contents = nullptr;
- }
- return hr;
- }
- void Helpers::TTReportLastIOErrorAsNeeded(BOOL ok, const char* msg)
- {
- if(!ok)
- {
- #ifdef _WIN32
- DWORD lastError = GetLastError();
- LPTSTR pTemp = NULL;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, 0, (LPTSTR)&pTemp, 0, NULL);
- fwprintf(stderr, _u("Error is: %s\n"), pTemp);
- LocalFree(pTemp);
- #else
- fprintf(stderr, "Error is: %i %s\n", errno, strerror(errno));
- #endif
- fprintf(stderr, "Message is: %s\n", msg);
- AssertMsg(false, "IO Error!!!");
- exit(1);
- }
- }
- //We assume bounded ascii path length for simplicity
- #define MAX_TTD_ASCII_PATH_EXT_LENGTH 64
- void Helpers::CreateTTDDirectoryAsNeeded(size_t* uriLength, char* uri, const char* asciiDir1, const wchar* asciiDir2)
- {
- if(*uriLength + strlen(asciiDir1) + wcslen(asciiDir2) + 2 > MAX_URI_LENGTH || strlen(asciiDir1) >= MAX_TTD_ASCII_PATH_EXT_LENGTH || wcslen(asciiDir2) >= MAX_TTD_ASCII_PATH_EXT_LENGTH)
- {
- wprintf(_u("We assume bounded MAX_URI_LENGTH for simplicity.\n"));
- wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2);
- exit(1);
- }
- int success = 0;
- int extLength = 0;
- extLength = sprintf_s(uri + *uriLength, MAX_TTD_ASCII_PATH_EXT_LENGTH, "%s%s", asciiDir1, TTD_HOST_PATH_SEP);
- if(extLength == -1 || MAX_URI_LENGTH < (*uriLength) + extLength)
- {
- wprintf(_u("Failed directory extension 1.\n"));
- wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2);
- exit(1);
- }
- *uriLength += extLength;
- success = TTDHostMKDir(uri, *uriLength);
- if(success != 0)
- {
- //we may fail because someone else created the directory -- that is ok
- Helpers::TTReportLastIOErrorAsNeeded(errno == EEXIST, "Failed to create directory");
- }
- char realAsciiDir2[MAX_TTD_ASCII_PATH_EXT_LENGTH];
- size_t asciiDir2Length = wcslen(asciiDir2) + 1;
- for(size_t i = 0; i < asciiDir2Length; ++i)
- {
- if(asciiDir2[i] > CHAR_MAX)
- {
- wprintf(_u("Test directory names can only include ascii chars.\n"));
- exit(1);
- }
- realAsciiDir2[i] = (char)asciiDir2[i];
- }
- extLength = sprintf_s(uri + *uriLength, MAX_TTD_ASCII_PATH_EXT_LENGTH, "%s%s", realAsciiDir2, TTD_HOST_PATH_SEP);
- if(extLength == -1 || MAX_URI_LENGTH < *uriLength + extLength)
- {
- wprintf(_u("Failed directory create 2.\n"));
- wprintf(_u("%S, %S, %ls\n"), uri, asciiDir1, asciiDir2);
- exit(1);
- }
- *uriLength += extLength;
- success = TTDHostMKDir(uri, *uriLength);
- if(success != 0)
- {
- //we may fail because someone else created the directory -- that is ok
- Helpers::TTReportLastIOErrorAsNeeded(errno == EEXIST, "Failed to create directory");
- }
- }
- void Helpers::GetTTDDirectory(const wchar* curi, size_t* uriLength, char* uri, size_t bufferLength)
- {
- TTDHostBuildCurrentExeDirectory(uri, uriLength, bufferLength);
- Helpers::CreateTTDDirectoryAsNeeded(uriLength, uri, "_ttdlog", curi);
- }
- JsTTDStreamHandle CALLBACK Helpers::TTCreateStreamCallback(size_t uriLength, const char* uri, size_t asciiNameLength, const char* asciiName, bool read, bool write)
- {
- AssertMsg((read | write) & (!read | !write), "Read/Write streams not supported yet -- defaulting to read only");
- if(uriLength + asciiNameLength + 1 > MAX_URI_LENGTH)
- {
- wprintf(_u("We assume bounded MAX_URI_LENGTH for simplicity."));
- exit(1);
- }
- char path[MAX_URI_LENGTH];
- memset(path, 0, MAX_URI_LENGTH);
- memcpy_s(path, MAX_URI_LENGTH, uri, uriLength);
- memcpy_s(path + uriLength, MAX_URI_LENGTH - uriLength, asciiName, asciiNameLength);
- JsTTDStreamHandle res = TTDHostOpen(uriLength + asciiNameLength, path, write);
- if(res == nullptr)
- {
- fprintf(stderr, "Failed to open file: %s\n", path);
- }
- Helpers::TTReportLastIOErrorAsNeeded(res != nullptr, "Failed File Open");
- return res;
- }
- bool CALLBACK Helpers::TTReadBytesFromStreamCallback(JsTTDStreamHandle handle, byte* buff, size_t size, size_t* readCount)
- {
- AssertMsg(handle != nullptr, "Bad file handle.");
- if(size > MAXDWORD)
- {
- *readCount = 0;
- return false;
- }
- BOOL ok = FALSE;
- *readCount = TTDHostRead(buff, size, (FILE*)handle);
- ok = (*readCount != 0);
- Helpers::TTReportLastIOErrorAsNeeded(ok, "Failed Read!!!");
- return ok ? true : false;
- }
- bool CALLBACK Helpers::TTWriteBytesToStreamCallback(JsTTDStreamHandle handle, const byte* buff, size_t size, size_t* writtenCount)
- {
- AssertMsg(handle != nullptr, "Bad file handle.");
- if(size > MAXDWORD)
- {
- *writtenCount = 0;
- return false;
- }
- BOOL ok = FALSE;
- *writtenCount = TTDHostWrite(buff, size, (FILE*)handle);
- ok = (*writtenCount == size);
- Helpers::TTReportLastIOErrorAsNeeded(ok, "Failed Read!!!");
- return ok ? true : false;
- }
- void CALLBACK Helpers::TTFlushAndCloseStreamCallback(JsTTDStreamHandle handle, bool read, bool write)
- {
- fflush((FILE*)handle);
- fclose((FILE*)handle);
- }
- void GetBinaryPathWithFileNameA(char *path, const size_t buffer_size, const char* filename)
- {
- char fullpath[_MAX_PATH];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char modulename[_MAX_PATH];
- PlatformAgnostic::SystemInfo::GetBinaryLocation(modulename, _MAX_PATH);
- _splitpath_s(modulename, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0);
- _makepath_s(fullpath, drive, dir, filename, nullptr);
- size_t len = strlen(fullpath);
- if (len < buffer_size)
- {
- memcpy(path, fullpath, len * sizeof(char));
- }
- else
- {
- len = 0;
- }
- path[len] = char(0);
- }
|