📜 ⬆️ ⬇️

How I transferred the file name from C ++ to Java

image
In cross-platform applications that just can not be found. Or write. Here, the other day they gave birth to the next hedgehog, they stepped on a carefully laid rake, this time under a poppy.



Let me remind you of the previous saga series: rake under Windows .
')
That is, we still have the same exotic hedgehog + python = barbed wire. This time, happiness came to us and we had a surprise on a poppy. Java in InDesign was integrated, it works, now we need to transfer the file name to our Java code written.

The Dark Knight: the Beginning


It all started so ordinary:
void FooExpFilter::ExportToStream( IPMStream* stream, IDocument* doc, IPMUnknown* targetboss, const PMString& formatName, UIFlags uiFlags) { IDFile outputFile; InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA); outputFile = fileData->GetSysFile(); SDKFileHelper fh(outputFile); PMString pathID = fh.GetPath(); WideString pathWID(pathID); std::string xID; StringUtils::ConvertWideStringToUTF8 (pathWID, xID); 

and worked on Mac and on Windows. While InDesign has not grown to version CS5.5. And then the happiness came to the log our favorite and epic java.io.FileNotFoundException .

Star Wars: The Empire Strikes Back


Aside : these entries in the “as if something did not work out” log file help a lot, I recommend. If, of course, logs are wisely written, and then (personally I saw!) Once from the abundance of logs, performance degradation turned out and a “coder” (C) wrote the log for 40 seconds, and without a log it worked for a half second. Hindus tried - they wrote their log4j with blackjack but without buffering.

We get a log from the client, and there - Macintosh HD :: Foo :: Bar !

Come to us in Prostokvashino - if you do not have ball gowns


Fast googling (how to translate carbon poppy paths in Unix) leads to detailed instructions on how to translate with your hands, given the mount points. And applescript as an example, what and in what order to ask the Finder. Aha, aha - that's what ObjectiveC lacked for complete happiness.

Having drank half a bucket of coffee, and dabbed the Adobe SDK, we find a solution worthy of ithappens. Here it is.

  IDFile outputFile; InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA); outputFile = fileData->GetSysFile(); // URL for java PMString pathJ = FileUtils::SysFileToFileURL(outputFile); WideString pathWJ(pathJ); std::string xj; StringUtils::ConvertWideStringToUTF8 (pathWJ, xj); 

and in Java there are 3 more lines:
  if(externFile.startsWith("file://")) { File externFd = new File(new java.net.URI(externFile)); externFile = externFd.getAbsolutePath(); } 


That is, not finding how to pass the path, we passed ... URL!

And it even works.

Disclaimer : I will not give up the correct example - how to translate the carbon paths in Unix without ObjectiveC Though irrelevant, but interesting. If it exists at all, and not “cut off the head and change :: to /”, I’m wrong myself.

Mind Games: How You Can Do Better


Update 1 : notorca suggested using a poppy CFURLCopyFileSystemPath :

 void FooExpFilter::ExportToStream( IPMStream* stream, IDocument* doc, IPMUnknown* targetboss, const PMString& formatName, UIFlags uiFlags) { IDFile outputFile; InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA); outputFile = fileData->GetSysFile(); #ifdef WINDOWS SDKFileHelper fh(outputFile); PMString pathID = fh.GetPath(); #endif #ifdef MACINTOSH FSSpec fsSpec; PMString pathID; OSErr err = FileUtils::IDFileToFSSpec(outputFile, fsSpec); if (err == noErr) { FSRef fsRef; err = MacFileUtils::FSSpecToFSRef(fsSpec, fsRef); if (err == noErr) { CFURLRef appURL = ::CFURLCreateFromFSRef(NULL, &fsRef); CFStringRef app_str = ::CFURLCopyFileSystemPath(appURL, kCFURLPOSIXPathStyle); if (app_str) { pathID.SetCFString(app_str); ::CFRelease(app_str); } if (appURL) ::CFRelease(appURL); } } #endif WideString pathWID(pathID); std::string xID; StringUtils::ConvertWideStringToUTF8 (pathWID, xID); 


Update 2 : And strizh gave another hint - you could use FileUtils :: FileURLToPosixPath , in this case the code becomes like this:

  IDFile outputFile; InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA); outputFile = fileData->GetSysFile(); #ifdef WINDOWS SDKFileHelper fh(outputFile); PMString pathID = fh.GetPath(); WideString pathWID(pathID); std::string xfinal; StringUtils::ConvertWideStringToUTF8 (pathWID, xfinal); #endif #ifdef MACINTOSH PMString pathJ = FileUtils::SysFileToFileURL(outputFile); WideString pathWJ(pathJ); std::string xj; StringUtils::ConvertWideStringToUTF8 (pathWJ, xj); std::string xfinal = FileUtils::FileURLToPosixPath(xj); #endif 


So if through the URL - then there are options. Without a transition path -> URL -> posix path while prompts have been received (no, I still do not agree to carry with me a piece on ObjectiveC).

Source: https://habr.com/ru/post/148115/


All Articles