Hello people,

I've just got Xalan 1.4, and it seems I've got a problem as well.

Look at the simple program:

XMLPlatformUtils::Initialize();
XalanTransformer::initialize();
XalanTransformer        theXalanTransformer;
std::ifstream   theStylesheetInputStream( "foo.xsl");
XSLTInputSource theStylesheetInputSource( &theStylesheetInputStream);
const XalanCompiledStylesheet* compiledStylesheet = 0;
int theResult = theXalanTransformer.compileStylesheet( theStylesheetInputSource, 
compiledStylesheet);
//theResult = theXalanTransformer.compileStylesheet( "foo.xsl", compiledStylesheet);
if(theResult != 0)
{
   cerr << "testXalan14 compileStylesheet Error: \n" << 
theXalanTransformer.getLastError()
        << endl
       << endl;
   return -1;
}
...

( foo.xsl is well-formed XSLT document.)
Xalan 1.3 did what I expected, i.e successfully compiled stylesheet.
Xalan 1.4 would not compile in such a way.
The output is

Fatal Error at (file <unknown>, line 1, column 1): Invalid document structure
testXalan14 compileStylesheet Error:
Invalid document structure

Looking at the Xalan source code, I found that the problem caused by
new StdBinInputStream::readBytes implementation.
After StdBinInputStream is initialized with ifstream pointer,
it never reads from file.

XSLTInputSource creates StdBinInputStream object with
m_blockingRead==false, so StdBinInputStream::readBytes tries to read
from stream in the following way:

m_stream.readsome(reinterpret_cast<char*>(toFill), maxToRead);

But readsome tries to read only from buffer, not from the underlying
file. As there are no bytes in buffer just after ifstream creation,
nothing is read... The result is the same as if file were zero bytes
length.

There is a simple program to test
std::ifstream   theStylesheetInputStream( "foo.xsl")
StdBinInputStream theBinInputStream( theStylesheetInputStream);
XMLByte szBuffer[64] = "";
int nReadBytes = theBinInputStream.readBytes( szBuffer, 
sizeof(szBuffer)/sizeof(szBuffer[0])-1);
szBuffer[sizeof(szBuffer)/sizeof(szBuffer[0])-1] = 0;
cout << " nReadBytes = " << nReadBytes << endl
     << " szBuffer   = " << szBuffer << endl;

The result is:
nReadBytes = 0
szBuffer   =

I suppose new code in StdBinInputStream::readBytes

#if !defined(XALAN_OLD_STREAM_HEADERS)
#if defined(XALAN_OLD_STYLE_CASTS)
    return m_stream.readsome((char*)toFill, maxToRead);
#else
     return m_stream.readsome(reinterpret_cast<char*>(toFill), maxToRead);
#endif
#else
     m_stream.read(toFill, maxToRead);
     return m_stream.gcount();
#endif

... should be shortened to:
     m_stream.read(toFill, maxToRead);
     return m_stream.gcount();

( Alternative is to create StdBinInputStream with
fBlockingRead=true in XSLTInputSource.)

Sincerely,
   Alexei Agafonov
   mailto:lucir@;ok.ru

Reply via email to