Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    OpenInputStream() works incorrect.

    Cinema 4D SDK
    2
    2
    499
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Y
      yaya
      last edited by yaya

      Language: C++
      Platform: Windows

      Hello.
      I am trying to realize the downloading of a future updates of my C++ plugin.
      I want to achieve in result the posibility to download the new file or folder from my web adress and replace the old one.
      For it I am using this code snipped: https://developers.maxon.net/docs/cpp/2023_2/page_maxonapi_files_inputstream.html#page_maxonapi_files_inputstream_use
      ("// This example loads a file from the web and saves it to the local file system.")

      But I receive an error on this line:

      const maxon::InputStreamRef inputStream = webFile.OpenInputStream() iferr_return;
      
      • Error (active) E0312 no suitable user-defined conversion from "maxon::MacroArgType<void (maxon::Resultmaxon::InputStreamRef)>" to "const maxon::InputStreamRef" exists*

      What am I doing wrong?

      On SDK help search there is no a link to a "InputStreamRef".

      The code:

      const maxon::Url webFile = (maxon::Url("https://www.mysite.com/Somevideo.mp4"_s))iferr_return; // just for tests
          
          // check if the given URL references a file on the web
          const maxon::UrlScheme scheme = webFile.GetScheme();
          const maxon::Bool      isHTTP = scheme == maxon::URLSCHEME_HTTP;
          const maxon::Bool      isHTTPS = scheme == maxon::URLSCHEME_HTTPS;
      
          if (isHTTP || isHTTPS)
          {
              // read data 
              // input stream
              webFile.OpenInputStream();
              const maxon::InputStreamRef inputStream = webFile.OpenInputStream() iferr_return;
              const maxon::Int length = inputStream.GetStreamLength() iferr_return;
      
              maxon::BaseArray<maxon::Char> data;
              data.Resize(length) iferr_return;
      
              inputStream.Read(data) iferr_return;
              inputStream.Close() iferr_return;
      
              // save data to file
      
              // prepare file name
              const maxon::Url localFile = (sad)iferr_return;
              const maxon::Url localFile = (targetFolder + webFile.GetName())iferr_return;
              // output stream
              const maxon::OutputStreamRef outputStream = localFile.OpenOutputStream() iferr_return;
              // write to file
              outputStream.Write(data) iferr_return;
              outputStream.Close() iferr_return;
          }
      

      https://www.ragdollplugin.com

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @yaya
        last edited by ferdinand

        Hello @yaya,

        thank you for reaching out to us. Your example does build for me in R23, at least regarding the mentioned line of code:

        const maxon::InputStreamRef inputStream = webFile.OpenInputStream() iferr_return;
        

        Your example is however incomplete, it is missing the include statement to include iostreams.h which is likely causing your error. But there should be more errors for you in this stretch of code, since for example the line const maxon::Url webFile = (maxon::Url("https://www.mysite.com/Somevideo.mp4"_s))iferr_return is also incorrect. Find a commented example at the end of my posting for details.

        On SDK help search there is no a link to a "InputStreamRef".

        The maxon API does provide in C++ a managed memory environment, i.e., garbage collection, akin to managed languages like C# or Python. Which means all objects are split into the actual object instance and references to that instance. The object instance is then reference counted and deallocated once there are no references to it anymore. So, when you have a ThingRef, it is actually just a reference to an instance of a ThingInterface (at least most of the time, copy-on-write object references do not have the Ref postfix, i.e., the reference for a COW ThingInterface would be called Thing). The Doxygen parser (the tool we are using for documentation) does struggle heavily with all the metaprogramming we do and cannot properly ingest Ref entities. This is a bit tricky subject we are aware of and working on to, but this will take some time.

        Long story short, you would have to search here for InputStreamInterface. There is also our Entity Creation Manual which does expand a bit on the topic of interfaces and their references.

        If you continue to have problems, please make sure to post your full code and not just a snippet, as it otherwise mostly guesswork for us to figure out where your problem lies.

        Cheers,
        Ferdinand

        // You must include this header in order to have access to the full interface definitions.
        #include "maxon\iostreams.h"
        
        maxon::Result<void> SomeFunction()
        {
          iferr_scope;
        
          // The iferr_return here was incorrect. In our example it is required because we concatenate there
          // two urls. UrlInterface.operator+ is a maxon::Result, i.e., requires error handling. Just 
          // initializing a Url does not have any error handling and therefor requires no iferr_return.
          const maxon::Url url("https://www.mysite.com/Somevideo.mp4"_s);
          const maxon::UrlScheme scheme = url.GetScheme();
          const maxon::Bool isHTTP = scheme == maxon::URLSCHEME_HTTP;
          const maxon::Bool isHTTPS = scheme == maxon::URLSCHEME_HTTPS;
        
          if (isHTTP || isHTTPS)
          {
            const maxon::InputStreamRef inputStream = url.OpenInputStream() iferr_return;
            const maxon::Int length = inputStream.GetStreamLength() iferr_return;
        
            maxon::BaseArray<maxon::Char> data;
            data.Resize(length) iferr_return;
        
            inputStream.Read(data) iferr_return;
            inputStream.Close() iferr_return;
        
            // trgetUrl was not defined in your/our example, so I did redefine it here as someUrl.
            const maxon::Url someUrl("https://www.yoursite.com/"_s);
            // This will be "https://www.yoursite.com/Somevideo.mp4", i.e., GetName returns the last 
            // component of a Url, e.g., "Somevideo.mp4" in this case. Here we need the iferr_return, since 
            // UrlInterface.operator+ can fail, i.e., return an error.
            const maxon::Url anotherUrl = (someUrl + url.GetName()) iferr_return;
            const maxon::OutputStreamRef outputStream = anotherUrl.OpenOutputStream() iferr_return;
        
            outputStream.Write(data) iferr_return;
            outputStream.Close() iferr_return;
          }
          return maxon::OK;
        }
        

        MAXON SDK Specialist
        developers.maxon.net

        Y 1 Reply Last reply Reply Quote 1
        • First post
          Last post