Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 14 additions & 38 deletions include/itkInputStreamBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
#ifndef itkInputStreamBase_h
#define itkInputStreamBase_h

#include "itkPipeline.h"
#include "itkWasmStringStream.h"

#include <ios>
#include <iosfwd> // For istream.
#include <memory> // For unique_ptr.
#include <string>
#include <sstream>
#include <fstream>

#include "WebAssemblyInterfaceExport.h"

Expand Down Expand Up @@ -54,52 +52,30 @@ class WebAssemblyInterface_EXPORT InputStreamBase
std::istream *
GetPointer()
{
return m_IStream;
return m_IStream.get();
}

void
SetJSON(const std::string & json)
{
if (m_DeleteIStream && m_IStream != nullptr)
{
delete m_IStream;
}
m_DeleteIStream = false;
m_WasmStringStream = WasmStringStream::New();
m_WasmStringStream->SetJSON(json.c_str());

m_IStream = &(m_WasmStringStream->GetStringStream());
}
SetJSON(const std::string & json);

virtual void
SetFileName(const std::string & fileName) = 0;

protected:
void
SetFile(const std::string & fileName, const std::ios_base::openmode openMode)
{
if (m_DeleteIStream && m_IStream != nullptr)
{
delete m_IStream;
}
m_IStream = new std::ifstream(fileName, openMode);
m_DeleteIStream = true;
}
SetFile(const std::string & fileName, const std::ios_base::openmode openMode);

InputStreamBase() = default;
virtual ~InputStreamBase()
{
if (m_DeleteIStream && m_IStream != nullptr)
{
delete m_IStream;
}
}

private:
std::istream * m_IStream{ nullptr };
bool m_DeleteIStream{ false };
// Move semantics for its derived classes:
InputStreamBase(InputStreamBase &&) = default;
InputStreamBase &
operator=(InputStreamBase &&) = default;

WasmStringStream::Pointer m_WasmStringStream;
virtual ~InputStreamBase();

private:
std::unique_ptr<std::istream> m_IStream;
};


Expand Down
24 changes: 23 additions & 1 deletion src/itkInputStreamBase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,38 @@
*
*=========================================================================*/
#include "itkInputStreamBase.h"
#include "itkPipeline.h"
#include "itkWasmStringStream.h"

#include <string>
#ifndef ITK_WASM_NO_MEMORY_IO
# include "itkWasmExports.h"
#endif

#include <fstream>
#include <sstream>

namespace itk
{
namespace wasm
{
void
InputStreamBase::SetJSON(const std::string & json)
{
const auto wasmStringStream = WasmStringStream::New();
wasmStringStream->SetJSON(json.c_str());
m_IStream = std::make_unique<std::stringstream>(std::move(wasmStringStream->GetStringStream()));
Copy link

Copilot AI Jul 25, 2025

Choose a reason for hiding this comment

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

This line attempts to move-construct a stringstream from another stringstream, but the GetStringStream() method likely returns a reference, not a movable object. This could result in compilation errors or unintended copying. Consider using a different approach to transfer the stream data.

Suggested change
m_IStream = std::make_unique<std::stringstream>(std::move(wasmStringStream->GetStringStream()));
std::stringstream tempStream = wasmStringStream->GetStringStream();
m_IStream = std::make_unique<std::stringstream>(tempStream.str());

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The change suggested by Copilot does not compile. Specifically:

    std::stringstream tempStream = wasmStringStream->GetStringStream();

This suggestion would try to copy-construct a std::stringstream, but std::stringstream is not copy-constructible!

std::stringstream is move-construcible, so the stringstream of a WasmStringStream object can be properly moved into another stringstream, as in the proposed PR. Especially because the WasmStringStream object itself is no longer used afterwards.

}


void
InputStreamBase::SetFile(const std::string & fileName, const std::ios_base::openmode openMode)
{
m_IStream = std::make_unique<std::ifstream>(fileName, openMode);
}


InputStreamBase::~InputStreamBase() = default;


bool
lexical_cast(const std::string & input, InputStreamBase & inputStream)
Expand Down
Loading