So, I've been trying to deserialize the IPXDefaultLibraryURLBookmark of the com.apple.Photos defaults (defaults read com.apple.Photos IPXDefaultLibraryURLBookmark) but no luck. Ideally I'd like a programmatic way in c++ to deserialize that value to retrieve the last known location of the photo
bookd0xUsersmateuscbPicturesPhotos Library.photoslibrary 0#˜ì5$r$Éò|åú¨A∫˙æJ file:///Macintosh HDÇ1tA∫‘}•$6465C0A4-1771-3C89-9055-147CEDFBBF2EÅÔ/∆72cd528f2dcfb4b3434986cf3caa02cc946333b8;00000000;00000000;0000000000000020;com.apple.app-sandbox.read-write;00000001;01000004;0000000002980783;/users/mateuscb/pictures/photos library.photoslibrary¥˛ˇˇˇdº‰#‘ î H ( 8 t0 †–Ä®
I know its not a bplist, since the first format specifier denotes bookd.
But I have no clue what that is. I'm somewhat new to OSX development, so this may be something very basic I'm missing.
I want to retrieve the: /users/mateuscb/pictures/photos library.photoslibrary portion so I can find the defaults photoslibrary.
Unless there is another way to retrieve the default photoslibrary path?
I figured out how to retrieve the path to the .photoslibrary. I used CFURLCreateByResolvingBookmarkData to get a CFURLRef from the plist then used CFURLGetFileSystemRepresentation to get the full path as a string.
Help from this sample to retrieve sandbox preferences: https://gist.github.com/glebd/4759724
Here is my full solution:
int main(int argc, const char * argv[]) {
bool success = FALSE;
UInt8 photosUrlString[PATH_MAX];
struct passwd *pwd = getpwuid(getuid());
if (pwd == NULL){
Log("Unable to retrieve current user");
return 0;
}
const char *home = pwd->pw_dir;
if (home == NULL){
Log("Unable to retrieve current user directory");
return 0;
}
CFMutableStringRef preferencesPath = CFStringCreateMutable(NULL, 0);
if (preferencesPath) {
CFStringAppend(preferencesPath, CFStringCreateWithCStringNoCopy(NULL, home, kCFStringEncodingUTF8, NULL));
CFStringAppend(preferencesPath, CFSTR("/Library/Containers/com.apple.Photos/Data/Library/Preferences/com.apple.Photos"));
} else {
Log("Unable to create CFString of user directory");
return 0;
}
CFPropertyListRef photosUrlPrefs = CFPreferencesCopyValue(CFSTR("IPXDefaultLibraryURLBookmark"), preferencesPath, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
CFRelease(preferencesPath);
if (photosUrlPrefs) {
CFTypeID prefsType = CFGetTypeID(photosUrlPrefs);
if (CFDataGetTypeID() == prefsType) {
CFDataRef photosUrlData = (CFDataRef) photosUrlPrefs;
CFErrorRef urlResolveError = nil;
CFURLRef photosUrl = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, photosUrlData, NULL, NULL, NULL, NULL, &urlResolveError);
if (photosUrl == NULL) {
if(urlResolveError != NULL) {
CFStringRef resolveErrorString = CFErrorCopyDescription(urlResolveError);
if (resolveErrorString != NULL) {
char resolveErrorCString[PATH_MAX];
if (CFStringGetCString((CFStringRef) resolveErrorString, resolveErrorCString, sizeof(resolveErrorCString), kCFStringEncodingUTF8)) {
Log("Error resolving URL: %s", resolveErrorCString);
}
CFRelease(resolveErrorString);
}
} else {
Log("Error resolving URL, no resolveError");
}
} else {
success = CFURLGetFileSystemRepresentation(photosUrl, false, photosUrlString, sizeof(photosUrlString));
CFRelease(photosUrl);
}
} else {
Log("Url plist value is not CFData");
}
if (photosUrlPrefs != NULL) {
CFRelease(photosUrlPrefs);
}
}
if(success) {
Log("path: %s", photosUrlString);
}
return 0;
}
Related
Following code is work really slow, almost 30 second to process 400 entities:
int page = 0;
org.springframework.data.domain.Page<MyEntity> slice = null;
while (true) {
if (slice == null) {
slice = repo.findAll(PageRequest.of(page, 400, Sort.by("date")));
} else {
slice = repo.findAll(slice.nextPageable());
}
if (!slice.hasNext()) {
break;
}
slice.getContent().forEach(v -> v.setApp(SApplication.NAME_XXX));
repo.saveAll(slice.getContent());
LOGGER.info("processed: " + page);
page++;
}
I use following instead, 4-6 sec per 400 entities (gcp lib to work with datastore)
Datastore service = DatastoreOptions.getDefaultInstance().getService();
StructuredQuery.Builder<?> query = Query.newEntityQueryBuilder();
int limit = 400;
query.setKind("ENTITY_KIND").setLimit(limit);
int count = 0;
Cursor cursor = null;
while (true) {
if (cursor != null) {
query.setStartCursor(cursor);
}
QueryResults<?> queryResult = service.run(query.build());
List<Entity> entityList = new ArrayList<>();
while (queryResult.hasNext()) {
Entity loadEntity = (Entity) queryResult.next();
Entity.Builder newEntity = Entity.newBuilder(loadEntity).set("app", SApplication.NAME_XXX.name());
entityList.add(newEntity.build());
}
service.put(entityList.toArray(new Entity[0]));
count += entityList.size();
if (entityList.size() == limit) {
cursor = queryResult.getCursorAfter();
} else {
break;
}
LOGGER.info("Processed: {}", count);
}
Why I can't use spring to do that batch processing?
Full discussion here: https://github.com/spring-cloud/spring-cloud-gcp/issues/1824
First:
you need to use correct lib version: at least 1.2.0.M2
Second:
you need to implement new method in repository interface:
#Query("select * from your_kind")
Slice<TestEntity> findAllSlice(Pageable pageable);
Final code looks like:
LOGGER.info("start");
int page = 0;
Slice<TestEntity> slice = null;
while (true) {
if (slice == null) {
slice = repo.findAllSlice(DatastorePageable.of(page, 400, Sort.by("date")));
} else {
slice = repo.findAllSlice(slice.nextPageable());
}
if (!slice.hasNext()) {
break;
}
slice.getContent().forEach(v -> v.setApp("xx"));
repo.saveAll(slice.getContent());
LOGGER.info("processed: " + page);
page++;
}
LOGGER.info("end");
I want to get size (in bytes) of allocation blocks of a removable volume.
In my Macos application, I use FSGetVolumeInfo method to get FSVolumeInfo object.
In FSVolumeInfo object, attribute "blockSize" is the right one.
However, method FSGetVolumeInfo is deprecated after Macos10.8.
Is there any function to replace?
Below is sample code with FSVolumeInfo :
const char* path = "/Volumes/Untitled";
FSCatalogInfo volCatalogInfo;
FSVolumeRefNum realVolRefNum;
FSVolumeInfo myVolumeinfo;
if ('\0' != path[0]) {
CFStringRef pathStr = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
CFURLRef volumePath = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, pathStr, kCFURLPOSIXPathStyle, false);
FSRef volumeRef;
if (CFURLGetFSRef(volumePath, &volumeRef)) {
OSStatus err = FSGetCatalogInfo(&volumeRef, kFSCatInfoVolume, &volCatalogInfo, NULL, NULL, NULL);
if (noErr == err) {
FSVolumeRefNum volRefNum = volCatalogInfo.volume;
err = FSGetVolumeInfo(volRefNum, 0, &realVolRefNum, kFSVolInfoGettableInfo, &myVolumeinfo, NULL, NULL);
if (noErr == err) {
printf("get volume info success!");
}
}
}
}
I would look into standard c function calls I think, statvfs() does what you want.
I am following this article for Select Multiple Images From Gallery in Xamarin Forms.
I completed the feature in android part but the picture path contains only the picture name, extensions are missing when saving path.
To upload the image to the server I need the complete image name with extension. So how can I save the complete path of the selected images with the extension?
Following method capture the image path:
public String GetRealPathFromURI(Android.Net.Uri contentURI)
{
try
{
ICursor imageCursor = null;
string fullPathToImage = "";
imageCursor = ContentResolver.Query(contentURI, null, null, null, null);
imageCursor.MoveToFirst();
int idx = imageCursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
if (idx != -1)
{
fullPathToImage = imageCursor.GetString(idx);
}
else
{
ICursor cursor = null;
var docID = DocumentsContract.GetDocumentId(contentURI);
var id = docID.Split(':')[1];
var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
var projections = new string[] { MediaStore.Images.ImageColumns.Data };
cursor = ContentResolver.Query(MediaStore.Images.Media.InternalContentUri, projections, whereSelect, new string[] { id }, null);
if (cursor.Count == 0)
{
cursor = ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, projections, whereSelect, new string[] { id }, null);
}
var colData = cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
cursor.MoveToFirst();
fullPathToImage = cursor.GetString(colData);
}
return fullPathToImage;
}
catch (Exception ex)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "Unable to get path", ToastLength.Long).Show();
}
return null;
}
The extension(.png or .jpg) was missing not from the GetRealPathFromURI(), it happens in ImageHelpers.SaveFile(). So I save the filename to another variable from the path using Path.GetFileName() like below and pass the complete filename when call ImageHelpers.SaveFile().
var fileName = Path.GetFileName(picturepath);
I am getting this error in unity:
5.50f3
Assets/Scripts/BaseClient/client.c s(14701,12): error CS0136: A local variable named 'text' cannot be declared in this scope because it would give a different meaning to 'text', which is already used in a 'child' scope to denote something else
Here is snippet of code:
case 126:
//String text = inStream.readString();
int frame = inStream.method435();
if (text.StartsWith("www."))
{
//openURL(text);
pktType = -1; return true;
}
if(text != null && frame != null)
{
updateStrings(text, frame);
sendFrame126(text, frame);
}
if (frame >= 18144 && frame <= 18244)
{
//clanList[frame - 18144] = text;
}
pktType = -1; return true;
The error is simply letting you know that you are reusing the same name for two variables:
int myVar = 0; // this one is global to the class
void Start()
{
int myVar = 20; // local variable, same name => problem
}
other case is within statement
if(condA)
{
int myResult = MethodA();
}
else
{
int myResult = MethodB();
}
This is likely what you are facing. Either give a different name in each subsection or get the variable out:
int myResult = -1;
if(condA)
{
myResult = MethodA();
}
else
{
myResult = MethodB();
}
This is likely what you are facing. Either give a different name in each
I am making Windows event log for my application that support Vista and above. I have a manifest created for each event, but I get a issue with the output type of win:Xml.
Below is what I specify for the data in event template.
<data name="StackTrace" inType="win:UnicodeString" outType="win:Xml">
</data>
I would like to set the StackTrace to be displayed as XML format in the Event logs. StackTrace must be input with well-formed XML. However, I still see it displayed as string(xs:string) in the Event Log viewer.
Do you know what I did wrong? How can I make it properly?
Below if update for my code:
const int NUM_OF_DATADESC = 6;
EVENT_DATA_DESCRIPTOR eventDataDesc[NUM_OF_DATADESC];
evDesc.Level = uLevel;
evDesc.Channel = nChannel;
evDesc.Keyword |= uKeyword;
for (int i = 0; i < NUM_OF_DATADESC; i++)
{
if (strings[i] != NULL)
EventDataDescCreate(&eventDataDesc[i], strings[i], ((ULONG)wcslen(strings[i])+1)*sizeof(WCHAR));
else
EventDataDescCreate(&eventDataDesc[i], L"", sizeof(WCHAR));
}
BOOL s = WriteEvent(evDesc,NUM_OF_DATADESC,&eventDataDesc[0]);
BOOL WriteEvent(EVENT_DESCRIPTOR eventID,DWORD userDataCount,PEVENT_DATA_DESCRIPTOR userData)
{
REGHANDLE hPub = NULL;
ULONG res = EventRegister(&MYCOMPANE_MYAPP_MYCOMPONENT, NULL, NULL, &hPub);
if (ERROR_SUCCESS != res){
return FALSE;
}
res = EventWrite(hPub, &eventID, userDataCount, userData);
if (ERROR_SUCCESS != res){
return FALSE;
}
EventUnregister(hPub);
return TRUE;
}
The code is working fine, but only issue with output type = win:Xml.