Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

NSURL changes for special filepath for Storage Files#1215

Merged
bbowman merged 3 commits into
microsoft:developfrom
bbowman:bbowman/NSURL_StorageFile
Oct 27, 2016
Merged

NSURL changes for special filepath for Storage Files#1215
bbowman merged 3 commits into
microsoft:developfrom
bbowman:bbowman/NSURL_StorageFile

Conversation

@bbowman

@bbowman bbowman commented Oct 24, 2016

Copy link
Copy Markdown
Member

Description:
This change adds the ability to create an NSURL with a Storage File and do all the
things one would expect to be able to accomplish with it like reading and writing
NSData and NSStreams. This is accomplished by making use of remnants of a "direct file"
url and the Windows FutureAccessCache to retreive the file at a later point.

EbrFile is refactored, minimized, and then extended to work with Storage Files.

How verified:
New functional test


This change is Reviewable

Description:
This change adds the ability to create an NSURL with a Storage File and do all the
things one would expect to be able to accomplish with it like reading and writing
NSData and NSStreams. This is accomplished by making use of remnants of a "direct file"
url and the Windows FutureAccessCache to retreive the file at a later point.

EbrFile is refactored, minimized, and then extended to work with Storage Files.

How verified:
New functional test
@bbowman

bbowman commented Oct 24, 2016

Copy link
Copy Markdown
Member Author

@rajsesh-msft @memontic-ms @DHowett-MSFT @bviglietta please take a look #Closed

// now that a token has been acquired, form a file path URL similar to a file reference URL based on it.
return [self initFileURLWithPath:[NSString stringWithFormat:@"/.file/id=%@", [NSString _stringWithHSTRING:token.Get()]]
isDirectory:NO];
}

@DHowett-MSFT DHowett-MSFT Oct 24, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like the use of special file: schema URLs for special behaviour... if there were some way to get this to interoperate with the existing URL protocol system, that'd be grand.

If not, I understand, and accept this as a cost... but it is clever and opaque. #Closed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I totally agree. It would be super grand to have a clear, coherent design here. Unfortunately the public apis for this force our hand a bit. The call pattern in specific that we are seeing for this scenario is:

UIImage *image = ... ;
if (!image && [imageURL isFileURL]) {
image = [UIImage imageWithContentsOfFile:[imageURL path]];
}

Which means the URL needs to return true for isFileURL and needs to interact withimageWithContentsOfFile when using just the raw path. The way to get this to interop easiest and most fully seemed to be to go ahead and use a real file URL with a custom path. Given that /.file/id=... URLs exist on the reference platform, this seemed sort of natural anyway but I definitely agree this isn't a clean design like I normally advocate for. :-(

RETURN_NULL_IF_FAILED(accessList->get_MaximumItemsAllowed(&maxItems));

// Documentation says 1000 but lets just make sure it was somthing valid.
RETURN_NULL_IF_FALSE(maxItems > 0);

@DHowett-MSFT DHowett-MSFT Oct 24, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ULL_IF_FALSE(maxItems > 0); [](start = 12, length = 27)

Is there a future world where they're unlimited and managed by the system? We may not want to break on those platforms. #Closed

Comment thread Frameworks/Foundation/NSURL.mm Outdated
{
std::lock_guard<std::mutex> guard(s_lock);

// protect the count check and addint logic with a lock since we don't want to race to add the last guy.

@DHowett-MSFT DHowett-MSFT Oct 24, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addint [](start = 39, length = 6)

nit: spelling? #Closed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep commented myself on that. Looks like some comments are special and don't show up in all PR tools. Hooray innovation

Comment thread Frameworks/Foundation/NSURL.mm Outdated
#include <COMIncludes.h>
#include "ErrorHandling.h"
#include <wrl/client.h>
#include <wrl\wrappers\corewrappers.h>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forward slashes



//
// UIApplicationTests

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UIApplicationTests [](start = 3, length = 18)

NSURLStorageFileTests. Also below.

@aballway aballway left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some places that are a bit sparse of comments but overall understandable

@Status Interoperable
*/
- (instancetype)initWithStorageFile:(RTObject<WSIStorageFile>*)storageFile {
ComPtr<IInspectable> comPtr = [storageFile comObj];

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: storageFile.comObj #Closed

RETURN_NULL_IF_FAILED(accessList->get_Entries(&entries));
RETURN_NULL_IF_FAILED(entries->get_Size(&count));

if (count >= maxItems) {

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this remove an item when we have exactly maxItems? #Closed

Comment thread Frameworks/Foundation/NSURL.mm Outdated
}

// now that a token has been acquired, form a file path URL similar to a file reference URL based on it.
return [self initFileURLWithPath:[NSString stringWithFormat:@"/.file/id=%@", [NSString _stringWithHSTRING:token.Get()]]

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use Strings::WideToNSString rather than directly using NSString internals #Closed

Comment thread Frameworks/Starboard/EbrFile.cpp Outdated
// Special file type for cached storage files.
fileToAdd = EbrStorageFile::CreateInstance(file, mode, share, pmode);
if (fileToAdd) {
return EbrFile::AddFile(std::move(fileToAdd));

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: flip this if so this only has one return at the end #Closed

Comment thread Frameworks/Starboard/EbrFile.cpp Outdated
}

int EbrFstat(int fd, struct stat* ret) {
return EbrFile::GetFile(fd)->Stat(ret);

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want these to blow up when no file is found? #Closed

int EbrStorageFile::Flush() {
std::lock_guard<std::recursive_mutex> lock(m_lock);

unsigned long long currentPosition{};

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: add int to type #Closed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but why?


In reply to: 84938944 [](ancestors = 84938944)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the implied int, but it's super not necessary hence super nit

std::lock_guard<std::recursive_mutex> lock(m_lock);

unsigned long long currentPosition{};
if (FAILED(m_randomAccessStream->get_Position(&currentPosition))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RETURN_IF_FAILED?

Comment thread Frameworks/Starboard/EbrStorageFile.cpp Outdated
return -1;
}

if (!src) {

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: make one if #Closed

Comment thread Frameworks/Starboard/EbrStorageFile.cpp Outdated
return -1;
}

UINT32 result;

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no shouty #Closed

TEST_CLASS_SETUP(NSURLStorageFileTestsSetup) {
return SUCCEEDED(FrameworkHelper::RunOnUIThread(&UIApplicationDefaultInitialize));
}

@aballway aballway Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add TEST_METHOD_CLEANUP so state doesn't leak into tests after this one #Closed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed; this requires cleanup.


In reply to: 84942793 [](ancestors = 84942793)

Comment thread Frameworks/Foundation/NSURL.mm Outdated
{
std::lock_guard<std::mutex> guard(s_lock);

// protect the count check and addint logic with a lock since we don't want to race to add the last guy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spelling

Comment thread Frameworks/Starboard/EbrStorageFile.cpp Outdated
return -1;
}

// TODO 1099: Add more properites that we can fill in stat.

@bbowman bbowman Oct 24, 2016

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps remove TODO. could add things like last modified time / created time but that seems probably not needed and not all storage files may even have that. Maybe just wait and do it later if people want it? #Closed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please remove TODO.


In reply to: 84801640 [](ancestors = 84801640)

}

int EbrStorageFile::Stat64i32(struct _stat64i32* ret) {
std::lock_guard<std::recursive_mutex> lock(m_lock);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider a templated internal function to remove duplicated stat code.

Comment thread Frameworks/Foundation/NSURL.mm Outdated
{
std::lock_guard<std::mutex> guard(s_lock);

// protect the count check and addint logic with a lock since we don't want to race to add the last guy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep commented myself on that. Looks like some comments are special and don't show up in all PR tools. Hooray innovation

// now that a token has been acquired, form a file path URL similar to a file reference URL based on it.
return [self initFileURLWithPath:[NSString stringWithFormat:@"/.file/id=%@", [NSString _stringWithHSTRING:token.Get()]]
isDirectory:NO];
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I totally agree. It would be super grand to have a clear, coherent design here. Unfortunately the public apis for this force our hand a bit. The call pattern in specific that we are seeing for this scenario is:

UIImage *image = ... ;
if (!image && [imageURL isFileURL]) {
image = [UIImage imageWithContentsOfFile:[imageURL path]];
}

Which means the URL needs to return true for isFileURL and needs to interact withimageWithContentsOfFile when using just the raw path. The way to get this to interop easiest and most fully seemed to be to go ahead and use a real file URL with a custom path. Given that /.file/id=... URLs exist on the reference platform, this seemed sort of natural anyway but I definitely agree this isn't a clean design like I normally advocate for. :-(

[condition signal];
}];

[condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 [](start = 66, length = 1)

This might sporadically fail on the build server.

Comment thread include/Foundation/NSURL.h Outdated
- (BOOL)getPromisedItemResourceValue:(id _Nullable*)value forKey:(NSString*)key error:(NSError* _Nullable*)error STUB_METHOD;
- (NSDictionary*)promisedItemResourceValuesForKeys:(NSArray*)keys error:(NSError* _Nullable*)error STUB_METHOD;

// MSFT Additions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSFT [](start = 3, length = 4)

WinOBJC


// Ok now lets read it out!!!
NSData* readData = [NSData dataWithContentsOfURL:storageUrl];
ASSERT_TRUE([readData isEqual:writeData]);

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASSERT_TRUE [](start = 4, length = 11)

Do we not have the OBJCEQ/OBJCNE macros in here? #Closed

[condition signal];
}

failure:^void(NSError* error) {

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did clang format this weird? #Closed

Comment thread Frameworks/Starboard/EbrFile.cpp Outdated
#include "EbrDevRandomFile.h"
#include "EbrStorageFile.h"

static const wchar_t* TAG = L"PlatformSupport";

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlatformSupport [](start = 30, length = 15)

This should be EbrFile now, presumably #Closed

return EbrFile::GetFile(fd)->Stat64i32(ret);
}

intptr_t EbrGetOSFHandle(int fd) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EbrGetOSFHandle [](start = 9, length = 15)

Does someone use this?

mkdir(dirOut);
return true;
}
static std::regex drive("[a-zA-Z]:");

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regex [](start = 16, length = 5)

I know this isn't your code, but we're using a whole regex engine to detect a single letter and a colon?!

Comment thread Frameworks/Starboard/EbrIOFile.cpp Outdated

std::shared_ptr<EbrFile> EbrIOFile::CreateInstance(const char* path, int mode, int share, int pmode) {
int fid{};
auto result = _sopen_s(&fid, CPathMapper(path), mode, share, pmode);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto [](start = 4, length = 4)

Only use auto when the return type cannot be easily expressed or is intuitively obvious from the righthand side.

}

EbrIOFile::~EbrIOFile() {
if (m_fid != -1) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_fid != - [](start = 8, length = 10)

How do we get an EbrIOFile with a fid of -1?

Comment thread Frameworks/Starboard/EbrStorageFile.cpp Outdated
@@ -0,0 +1,351 @@
//******************************************************************************
//
// Copyright (c) Microsoft Corporation. All rights reserved.

@rajsesh rajsesh Oct 25, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the corporation here. #Closed

@msft-Jeyaram

msft-Jeyaram commented Oct 25, 2016

Copy link
Copy Markdown

#define __EBRPLATFORM_H

#pragma once #Closed


Refers to: Frameworks/include/Platform/EbrPlatform.h:18 in 4e817ad. [](commit_id = 4e817ad, deletion_comment = False)

#include "EbrDevRandomFile.h"

std::shared_ptr<EbrFile> EbrDevRandomFile::CreateInstance(const char* path, int mode, int share, int pmode) {
if (strcmp(path, "/dev/urandom") == 0) {

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strcmp [](start = 8, length = 6)

use strncmp #Closed

#pragma once

#include <io.h>
#include <stdio.h>

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include [](start = 1, length = 7)

nit: Import #Closed

ComPtr<IRandomAccessStream>&& randomAccessStream,
bool shouldAppend,
bool shouldAllowWrite) :
m_storageFile(storageFile),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storageFile [](start = 26, length = 11)

Why pass-by-rvalue-reference with std::move on the outside (keeping external consumers aware of our internals) instead of pass-by-value with std::move on the inside? There does not appear to be consensus on this on the internet at large, but it looks like a lot of people lean towards the second.

@bbowman

bbowman commented Oct 25, 2016

Copy link
Copy Markdown
Member Author

Review status: 0 of 22 files reviewed at latest revision, 19 unresolved discussions.


Frameworks/Foundation/NSURL.mm, line 38 at r1 (raw file):

Previously, msft-Jeyaram (Ram) wrote…

forward slashes

@msft-Jeyaram you should get a better picture.

Frameworks/Foundation/NSURL.mm, line 922 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

super nit: storageFile.comObj

Won't fix. I prefer message send syntax as its more clear what is going on with the objects involved. This is especially true in interop code with C++ classes like ComPtr where . operator means a very different thing.

Frameworks/Foundation/NSURL.mm, line 940 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

ULL_IF_FALSE(maxItems > 0); [](start = 12, length = 27)

Is there a future world where they're unlimited and managed by the system? We may not want to break on those platforms.

I agree that we wouldn't want to break in that case but that is ultimately a concern for the api developer not us. I need to guard against maxItems <= 0 for any sort of reasonable for loop / boundary checks so if they want to introduce the notion of an unbounded collection, a new field would be added or something because any sentinel value for this extra logic may mess up existing code (imagine if I blindly did a while(i <= maxItems) loop or something). So won't fix. We will address that if and when new semantics are introduced but not guess at them unless you are thinking of something different that would be more robust?

Frameworks/Foundation/NSURL.mm, line 949 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

addint [](start = 39, length = 6)

nit: spelling?

Done.

Frameworks/Foundation/NSURL.mm, line 954 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

should this remove an item when we have exactly maxItems?

It should. And does?

Frameworks/Foundation/NSURL.mm, line 966 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: use Strings::WideToNSString rather than directly using NSString internals

Done.

Frameworks/Starboard/EbrFile.cpp, line 95 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: flip this if so this only has one return at the end

OK. not sure I like it better but ok.

Frameworks/Starboard/EbrFile.cpp, line 109 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

do we want these to blow up when no file is found?

Hmm I guess return -1 would be nicer.

Frameworks/Starboard/EbrFile.cpp, line 168 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

this always returns true? make a void/just return at the end if we can't change the signature for some reason

didn't mess with this guy. I want to expunge / rewrite the mapping logic too at some point but not in this review probably.

Frameworks/Starboard/EbrFile.cpp, line 253 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: braces

Ugh you and reviewing code that isn't mine and making me do the right thing and clean up whats around me. Darn you!!!!

Frameworks/Starboard/EbrIOFile.cpp, line 24 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

why braces here?

Hooray initializing variables!!!! If you don't do this or an assignment on release mode, the value of fid will be random stack junk until something more useful happens. As this is an out parameter, it is generally customary to initialize it yourself ahead of time if possible so that any failure conditions don't leave you with junk that you may accidentially use later.

I generally prefer the {} methodology as it universally works in C++ (i.e. inits structs classes etc too)


Frameworks/Starboard/EbrIOFile.cpp, line 27 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: ternary return

Eh. looked less clean to me. Going to leave it.

Frameworks/Starboard/EbrStorageFile.cpp, line 95 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

super nit: add int to type

that isn't the same ...

Frameworks/Starboard/EbrStorageFile.cpp, line 96 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

RETURN_IF_FAILED?

i didn't want to co-opt HRESULT into int returns. It is _generally_ true that failure HRs are negative but that is a little different. I could add a RETURN_X_IF_FAILED but that seems maybe overkill as I don't know how many other people will need that sort of translation.

Frameworks/Starboard/EbrStorageFile.cpp, line 250 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: make one if

Done.

Frameworks/Starboard/EbrStorageFile.cpp, line 279 at r1 (raw file):

Previously, aballway (AJ Ballway) wrote…

nit: no shouty

used for interop with WriteAsync. Won't fix.

tests/functionaltests/FunctionalTests.cpp, line 649 at r1 (raw file):

Previously, memontic-ms (Meredith Monticello) wrote…

UIApplicationTests [](start = 3, length = 18)

NSURLStorageFileTests. Also below.

Done.

Comments from Reviewable

#Closed

}

boolean success = false;
if (FAILED(AwaitResult(outStream, &IOutputStream::FlushAsync, &success))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AwaitResult [](start = 15, length = 11)

Will this not break due to the vtable thunk compiler bug?

}

ComPtr<IBuffer> dataRead;
if (FAILED(AwaitProgressComplete(inStream, &IInputStream::ReadAsync, rawDataBuffer.Get(), buffer.size(), InputStreamOptions_None, &dataRead))) {

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AwaitProgressComplete [](start = 15, length = 21)

As above? #Closed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am very surprised this works.


In reply to: 84969356 [](ancestors = 84969356)

Comment thread Frameworks/Starboard/EbrFile.cpp Outdated
}

int EbrFflush(int fd) {
return EbrFile::GetFile(fd)->Flush();

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetFile [](start = 20, length = 7)

invalid pointer when we can't find the file?
Deal with grace or not? #Closed

}

bool EbrRename(const char* path1, const char* path2) {
return rename(CPathMapper(path1), CPathMapper(path2)) == 0;

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n rename(CPathMapper(path1), CPathMapper(path2)) == 0; [](start = 9, length = 54)

nit: Log errno if failure? #Closed

/**
@Status Interoperable
*/
- (instancetype)initWithStorageFile:(RTObject<WSIStorageFile>*)storageFile {

@DHowett-MSFT DHowett-MSFT Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initWithStorageFile [](start = 16, length = 19)

perhaps this should be initWithPathToStorageFile, since you can't really have a "URL" with a "storage file" #Closed

char g_WritableFolder[2048] = ".";

void EbrSetWritableFolder(const char* folder) {
strcpy_s(g_WritableFolder, folder);

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strcpy_s [](start = 3, length = 9)

This can fail, are we staying silent? log the error? #Closed

@DHowett-MSFT

Copy link
Copy Markdown

🕐


#define FSROOT "."
#define mkdir _mkdir
char g_WritableFolder[2048] = ".";

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2048 [](start = 22, length = 4)

where does this value come from?
MAX_PATH? #Closed

return g_WritableFolder;
}

bool EbrGetRootMapping(const char* dirName, char* dirOut, uint32_t maxLen) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dirOut [](start = 50, length = 6)

can this be invalid?

return true;
}
if (_stricmp(dirName, "Documents") == 0) {
sprintf_s(dirOut, maxLen, "%s\\Documents", g_WritableFolder);

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%s\Documents" [](start = 35, length = 14)

Put the directory names/path strings in an internal header as a const/define?
This would make future maintenance easier


bool EbrGetRootMapping(const char* dirName, char* dirOut, uint32_t maxLen) {
if (dirName == NULL) {
strcpy_s(dirOut, maxLen, FSROOT);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strcpy_s [](start = 8, length = 8)

what is the copy fails? we end up returning true regardless.

if (strcmp(ent.fileName, ".") == 0 || strcmp(ent.fileName, "..") == 0)
continue;

char fullPath[4096]; // max path?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4096 [](start = 34, length = 4)

MAX_PATH?


if (result != 0) {
return nullptr;
}

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if(_sopen_s(&fid, CPathMapper(path), mode, share, pmode) != 0 ) {
return nullptr;
} #Closed

Comment thread Frameworks/Starboard/EbrStorageFile.cpp Outdated
// Check to see if this path is a file id path.
static const std::string c_fileIdPreamble = "/.file/id=";

RETURN_NULL_IF_FALSE(0 == strncmp(path, c_fileIdPreamble.c_str() , c_fileIdPreamble.length()));

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path [](start = 38, length = 4)

invalid path pointer? #Closed

@bbowman

bbowman commented Oct 25, 2016

Copy link
Copy Markdown
Member Author

Review status: 0 of 22 files reviewed at latest revision, 41 unresolved discussions.


Frameworks/Starboard/EbrDevRandomFile.cpp, line 20 at r1 (raw file):

Previously, msft-Jeyaram (Ram) wrote…

strcmp [](start = 8, length = 6)

use strncmp

Done.

Frameworks/Starboard/EbrDevRandomFile.h, line 19 at r1 (raw file):

Previously, msft-Jeyaram (Ram) wrote…

include [](start = 1, length = 7)

nit: Import

meh. won't fix. These guys are all straight c++ and just happen to be clang compiled for funsies. No need to introduce objC isms if we don't need it.

Frameworks/Starboard/EbrFile.cpp, line 36 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

PlatformSupport [](start = 30, length = 15)

This should be EbrFile now, presumably

sure.

Frameworks/Starboard/EbrFile.cpp, line 116 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

EbrGetOSFHandle [](start = 9, length = 15)

Does someone use this?

yes.

Frameworks/Starboard/EbrFile.cpp, line 208 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

regex [](start = 16, length = 5)

I know this isn't your code, but we're using a whole regex engine to detect a single letter and a colon?!

apparently yes.

Frameworks/Starboard/EbrIOFile.cpp, line 25 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

auto [](start = 4, length = 4)

Only use auto when the return type cannot be easily expressed or is intuitively obvious from the righthand side.

fair

Frameworks/Starboard/EbrIOFile.cpp, line 38 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

m_fid != - [](start = 8, length = 10)

How do we get an EbrIOFile with a fid of -1?

well its passed in from the ctor so it could presumably happen. Given the new pattern of CreateInstance it shouldn't unless _sopen_s returns 0 but fid is assigned -1.

Frameworks/Starboard/EbrStorageFile.cpp, line 3 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

Drop the corporation here.

Done.

Frameworks/Starboard/EbrStorageFile.cpp, line 78 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

storageFile [](start = 26, length = 11)

Why pass-by-rvalue-reference with std::move on the outside (keeping external consumers aware of our internals) instead of pass-by-value with std::move on the inside? There does not appear to be consensus on this on the internet at large, but it looks like a lot of people lean towards the second.

The reasoning here is to save an addRef Release pair. The consensus I think we should go with is:
  1. Use raw * / ** at ABI boundary.
  2. use const ComPtr& as a non transferring input argument
  3. use ComPtr&& to transfer ownership.

3 could also be a Detach Attach here but as its internal to this module (and I think imma go ahead and make the ctors private to enforce CreateInstance use) it seems cleaner to keep the jacket and pass it off rather than unwrap and rewrap around the callsite?


Frameworks/Starboard/EbrStorageFile.cpp, line 106 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

AwaitResult [](start = 15, length = 11)

Will this not break due to the vtable thunk compiler bug?

No! (Well not anymore). This file is ClCompile. I made that change while trying to figure out what was up.

Frameworks/Starboard/EbrStorageFile.cpp, line 137 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

Yes, please remove TODO.


In reply to: 84801640 [](ancestors = 84801640)

Done.

Frameworks/Starboard/EbrStorageFile.cpp, line 149 at r1 (raw file):

Previously, bbowman wrote…

consider a templated internal function to remove duplicated stat code.

Done.

Frameworks/Starboard/EbrStorageFile.cpp, line 167 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

{}; [](start = 27, length = 3)

{} are overkill for scalar types in this case..

not really? still needs initialized and this is a universal way to do it.

Frameworks/Starboard/EbrStorageFile.cpp, line 211 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

I am very surprised this works.


In reply to: 84969356 [](ancestors = 84969356)

Magic! (ClCompile as per other comment. Super not obvious due to change being hidden in vcxproj goop)

Frameworks/Starboard/EbrStorageFile.cpp, line 215 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

th = 0; [](start = 21, length = 7)

nit: Why = 0 here and {} above?

Cause I'm fickle. (or more likely I copy pasta'ed from elsewhere)

Frameworks/Starboard/EbrStorageFile.cpp, line 232 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

It bothers me so much that ReadAsync can give you a different buffer than the one you provided, effectively eliminating nocopy optimizations. Is there something we can do to fix that?

Bitch and moan to the API implementors to make a less shitty interface in a future version.

Frameworks/Starboard/EbrStorageFile.cpp, line 243 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

short circuit for count 0?

sure why not.

Frameworks/Starboard/EbrStorageFile.cpp, line 244 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

fwrite returns a size_t, and write returns a ssize_t; I'd prefer that if we're going to pretend to be POSIX we follow their signatures. This gets rid of the cast on 289, too.

yeah there were a few signature weirdnesses that I didn't address here as some will spill out to the public interface. Like int64 seek accepting an int64 arg but not returning an int64 position. Hilarious. I'll be a good dev I guess. You guys are just so demanding :-p

Frameworks/Starboard/EbrStorageFile.cpp, line 279 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

result [](start = 11, length = 6)

This probably wants to be initialized.

indeed.

include/Foundation/NSURL.h, line 237 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

MSFT [](start = 3, length = 4)

WinOBJC

Done.

tests/functionaltests/Tests/NSURLStorageFileTests.mm, line 35 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

Did clang format this weird?

clang doesn't format for me anymore :-( someone was going to check something in to fix that but I haven't pulled recently.

tests/functionaltests/Tests/NSURLStorageFileTests.mm, line 40 at r1 (raw file):

Previously, rajsesh-msft (Raj Seshasankaran) wrote…

2 [](start = 66, length = 1)

This might sporadically fail on the build server.

can increase to 10? should never hit timeout but just so tests dont hang.

tests/functionaltests/Tests/NSURLStorageFileTests.mm, line 65 at r1 (raw file):

Previously, DHowett-MSFT (Dustin L. Howett (MSFT)) wrote…

ASSERT_TRUE [](start = 4, length = 11)

Do we not have the OBJCEQ/OBJCNE macros in here?

Hilariously no. Not for TAEF functional test interop with gtest macros.

Comments from Reviewable

RETURN_NULL_IF_FAILED(storageApplicationPermissionsStatics->get_FutureAccessList(&accessList));

// See how close we are to the cap.
uint32_t maxItems = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would help to move this to a private function, so the init method isn't doing too many things..

@rajsesh

rajsesh commented Oct 25, 2016

Copy link
Copy Markdown
Contributor

:shipit:

std::lock_guard<std::recursive_mutex> lock(m_lock);

unsigned long long currentPosition{};
if (FAILED(m_randomAccessStream->get_Position(&currentPosition))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (FAILED(m_randomAccessStream->get_Position(&currentPosition))) { [](start = 3, length = 68)

RETURN_RESULT_IF_FAILED

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized this change is not in the repo. Still doesn't hurt to introduce it.


In reply to: 84979111 [](ancestors = 84979111)

ComPtr<IOutputStream> outStream;
if (FAILED(m_randomAccessStream->GetOutputStreamAt(currentPosition, &outStream))) {
return -1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, this and below can be covered via the MACRO

unsigned char* rawBytes = nullptr;
if (FAILED(byteAccess->Buffer(&rawBytes))) {
return -1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, the macro introduction of RETURN_RESULT_IF_FAILED(.......,-1);
would help allot here.

@msft-Jeyaram

Copy link
Copy Markdown

Review status: 0 of 22 files reviewed at latest revision, 55 unresolved discussions.


Frameworks/Starboard/EbrFile.cpp, line 3 at r1 (raw file):

//******************************************************************************
//
// Copyright (c) Microsoft Corporation. All rights reserved.

drop corporation


Comments from Reviewable

Comment thread include/Foundation/NSURL.h Outdated
- (BOOL)getPromisedItemResourceValue:(id _Nullable*)value forKey:(NSString*)key error:(NSError* _Nullable*)error STUB_METHOD;
- (NSDictionary*)promisedItemResourceValuesForKeys:(NSArray*)keys error:(NSError* _Nullable*)error STUB_METHOD;

// MSFT Additions

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSFT [](start = 3, length = 4)

WINOBJC? #Closed

// Lets write some data!!!!
unsigned char rawDataToWrite[] = { 'a', 'b', 'c' };
NSData* writeData = [NSData dataWithBytesNoCopy:rawDataToWrite length:_countof(rawDataToWrite) freeWhenDone:NO];
[writeData writeToURL:storageUrl options:0 error:nil];

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[writeData writeToURL:storageUrl options:0 error:nil]; [](start = 2, length = 56)

ASSERT_TRUE([writeData writeToURL:storageUrl options:0 error:nil]); #Closed

@aballway

Copy link
Copy Markdown
Contributor

Frameworks/Starboard/EbrStorageFile.cpp, line 279 at r1 (raw file):

Previously, bbowman wrote…

indeed.

uint32_t then?

Comments from Reviewable


// Now with appending!
writeData = [NSData dataWithBytesNoCopy:rawDataToWrite length:_countof(rawDataToWrite) freeWhenDone:NO];
[writeData writeToURL:storageUrl options:NSDataWritingWithoutOverwriting error:nil];

@msft-Jeyaram msft-Jeyaram Oct 25, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writeData writeToURL:storageUrl [](start = 5, length = 31)

check for success, as here and other writes #Closed

@msft-Jeyaram

Copy link
Copy Markdown

🕐

ASSERT_FALSE_MSG(true, "FAILED: Waiting for download timed out!");
}
[condition lock];
ASSERT_TRUE_MSG( (downloadLocation || downloadResponse || downloadError) ||

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASSERT_TRUE_MSG( (downloadLocation || downloadResponse || downloadError) || [](start = 3, length = 77)

some of these don't handle spurious wakeups well but its at least a lot better than before. NSCondition needs locking and if you signal before a wait it just goes into the ether so needed another piece of information to check against.

SB_EXPORT int EbrFstat64i32(int fd, struct _stat64i32* ret);
SB_EXPORT int EbrRead(int fd, void* dest, size_t count);
SB_EXPORT int EbrWrite(int fd, const void* src, size_t count);
SB_EXPORT int EbrLseek(int fd, __int64 pos, int whence);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int [](start = 10, length = 3)

@DHowett-MSFT @msft-Jeyaram still working on this bit. Got very much sidetracked from test failures due to ridiculously wrong NSCondition use.

@bbowman bbowman merged commit f1b05d3 into microsoft:develop Oct 27, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants