You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xerces.apache.org by Kelly Beard <ke...@gmail.com> on 2017/01/12 21:29:54 UTC

does anyone use resetMemBufInputSource()?

Lets say you have a bit of code that reads characters off of a socket, and
you save them to a vector<char>.  You call this vector<char> 'big_buf'.

You have this code to dump your vector<char> to a char[]:

char *DumpVectorToChar(vector<char>& buf)
{
    char *ret_val = 0;

    int size = buf.size();                              // Get vector size
    vector<char>::iterator buf_end = buf.end();         // Should prevent
unnecessary calls to end()
    if (size > 0) {
        ret_val = new char[size + 1];
        if (ret_val != 0) {                     // Don't assume you got
anything
            int i = 0;
            for (vector<char>::iterator it = buf.begin(); it != buf_end;
++it) {        // Copy vector over
                ret_val[i++] = *it;
            }
            ret_val[i] = '\0';          // null-terminate
        }
    }

    return ret_val;         // return ptr to memory or null (unlikely)
}

somewhere down in your code you have this:

    if (isComplete) {
        int size = big_buf.size();

        // DumpVectorToChar() bolted for failed on new[], so bolt out of
here.
        if (cBuf == 0) {
            throw runtime_error("XMLSocketApp::doreceive(bool& isComplete,
vector<char>& ret_buf) "
                "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
        }

        m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);
        delete [] cBuf;

        if (m_defaultHandler != 0) {
            m_parser->setContentHandler(m_defaultHandler);
        }
        if (m_errorHandler != 0) {
            m_parser->setErrorHandler(m_errorHandler);
        }
        m_parser->parse(*m_memBufIS);
    }

You have a program that calls this routine.  It crashes, but not all of the
time.  It does crash when you have your debug flag set to no (of course),
works fine when it is on.  You know this is a sign of a pointer problem.
So, on a hunch and with prayer beads in tow, you do this:

    if (isComplete) {
        int size = big_buf.size();

        // DumpVectorToChar() bolted for failed on new[], so bolt out of
here.
        if (cBuf == 0) {
            throw runtime_error("XMLSocketApp::doreceive(bool& isComplete,
vector<char>& ret_buf) "
                "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
        }

        m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);

        if (m_defaultHandler != 0) {
            m_parser->setContentHandler(m_defaultHandler);
        }
        if (m_errorHandler != 0) {
            m_parser->setErrorHandler(m_errorHandler);
        }
        m_parser->parse(*m_memBufIS);
        delete [] cBuf;
    }

See if you can spot the difference.  :-)

I was under the impression that resetMemBufInputSource() would make its own
internal copy of the buffer passed to it.  True?  I generally find the
documentation for Xerces is lacking in these little detail member routines.

-- 
Kelly Beard

Re: does anyone use resetMemBufInputSource()?

Posted by Kelly Beard <ke...@gmail.com>.
Thank you.  I did dig up the source code (I shouldn't have to do that, but
whatever).  Moving my delete[] after parse() seems to have done the trick.

On Fri, Jan 13, 2017 at 9:02 AM, Vitaly Prapirny <ma...@mebius.net> wrote:

> Hi Kelly,
>
> This is the implementation:
> void MemBufInputSource::resetMemBufInputSource(const XMLByte* const
> srcDocBytes
>                                              , const XMLSize_t
>  byteCount)
> {
>     fByteCount = byteCount;
>     fSrcBytes  = srcDocBytes;
> }
> So answer to your question is:
>  No, it doesn't make internal copy of data.
>
> Good luck!
>    Vitaly
>
>
>
> Kelly Beard wrote:
>
>> Lets say you have a bit of code that reads characters off of a socket, and
>> you save them to a vector<char>.  You call this vector<char> 'big_buf'.
>>
>> You have this code to dump your vector<char> to a char[]:
>>
>> char *DumpVectorToChar(vector<char>& buf)
>> {
>>      char *ret_val = 0;
>>
>>      int size = buf.size();                              // Get vector
>> size
>>      vector<char>::iterator buf_end = buf.end();         // Should prevent
>> unnecessary calls to end()
>>      if (size > 0) {
>>          ret_val = new char[size + 1];
>>          if (ret_val != 0) {                     // Don't assume you got
>> anything
>>              int i = 0;
>>              for (vector<char>::iterator it = buf.begin(); it != buf_end;
>> ++it) {        // Copy vector over
>>                  ret_val[i++] = *it;
>>              }
>>              ret_val[i] = '\0';          // null-terminate
>>          }
>>      }
>>
>>      return ret_val;         // return ptr to memory or null (unlikely)
>> }
>>
>> somewhere down in your code you have this:
>>
>>      if (isComplete) {
>>          int size = big_buf.size();
>>
>>          // DumpVectorToChar() bolted for failed on new[], so bolt out of
>> here.
>>          if (cBuf == 0) {
>>              throw runtime_error("XMLSocketApp::doreceive(bool&
>> isComplete,
>> vector<char>& ret_buf) "
>>                  "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
>>          }
>>
>>          m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);
>>          delete [] cBuf;
>>
>>          if (m_defaultHandler != 0) {
>>              m_parser->setContentHandler(m_defaultHandler);
>>          }
>>          if (m_errorHandler != 0) {
>>              m_parser->setErrorHandler(m_errorHandler);
>>          }
>>          m_parser->parse(*m_memBufIS);
>>      }
>>
>> You have a program that calls this routine.  It crashes, but not all of
>> the
>> time.  It does crash when you have your debug flag set to no (of course),
>> works fine when it is on.  You know this is a sign of a pointer problem.
>> So, on a hunch and with prayer beads in tow, you do this:
>>
>>      if (isComplete) {
>>          int size = big_buf.size();
>>
>>          // DumpVectorToChar() bolted for failed on new[], so bolt out of
>> here.
>>          if (cBuf == 0) {
>>              throw runtime_error("XMLSocketApp::doreceive(bool&
>> isComplete,
>> vector<char>& ret_buf) "
>>                  "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
>>          }
>>
>>          m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);
>>
>>          if (m_defaultHandler != 0) {
>>              m_parser->setContentHandler(m_defaultHandler);
>>          }
>>          if (m_errorHandler != 0) {
>>              m_parser->setErrorHandler(m_errorHandler);
>>          }
>>          m_parser->parse(*m_memBufIS);
>>          delete [] cBuf;
>>      }
>>
>> See if you can spot the difference.  :-)
>>
>> I was under the impression that resetMemBufInputSource() would make its
>> own
>> internal copy of the buffer passed to it.  True?  I generally find the
>> documentation for Xerces is lacking in these little detail member
>> routines.
>>
>>
>


-- 
Kelly Beard

Re: does anyone use resetMemBufInputSource()?

Posted by Vitaly Prapirny <ma...@mebius.net>.
Hi Kelly,

This is the implementation:
void MemBufInputSource::resetMemBufInputSource(const XMLByte* const  srcDocBytes
                                              , const XMLSize_t       byteCount)
{
     fByteCount = byteCount;
     fSrcBytes  = srcDocBytes;
}
So answer to your question is:
  No, it doesn't make internal copy of data.

Good luck!
    Vitaly


Kelly Beard wrote:
> Lets say you have a bit of code that reads characters off of a socket, and
> you save them to a vector<char>.  You call this vector<char> 'big_buf'.
>
> You have this code to dump your vector<char> to a char[]:
>
> char *DumpVectorToChar(vector<char>& buf)
> {
>      char *ret_val = 0;
>
>      int size = buf.size();                              // Get vector size
>      vector<char>::iterator buf_end = buf.end();         // Should prevent
> unnecessary calls to end()
>      if (size > 0) {
>          ret_val = new char[size + 1];
>          if (ret_val != 0) {                     // Don't assume you got
> anything
>              int i = 0;
>              for (vector<char>::iterator it = buf.begin(); it != buf_end;
> ++it) {        // Copy vector over
>                  ret_val[i++] = *it;
>              }
>              ret_val[i] = '\0';          // null-terminate
>          }
>      }
>
>      return ret_val;         // return ptr to memory or null (unlikely)
> }
>
> somewhere down in your code you have this:
>
>      if (isComplete) {
>          int size = big_buf.size();
>
>          // DumpVectorToChar() bolted for failed on new[], so bolt out of
> here.
>          if (cBuf == 0) {
>              throw runtime_error("XMLSocketApp::doreceive(bool& isComplete,
> vector<char>& ret_buf) "
>                  "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
>          }
>
>          m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);
>          delete [] cBuf;
>
>          if (m_defaultHandler != 0) {
>              m_parser->setContentHandler(m_defaultHandler);
>          }
>          if (m_errorHandler != 0) {
>              m_parser->setErrorHandler(m_errorHandler);
>          }
>          m_parser->parse(*m_memBufIS);
>      }
>
> You have a program that calls this routine.  It crashes, but not all of the
> time.  It does crash when you have your debug flag set to no (of course),
> works fine when it is on.  You know this is a sign of a pointer problem.
> So, on a hunch and with prayer beads in tow, you do this:
>
>      if (isComplete) {
>          int size = big_buf.size();
>
>          // DumpVectorToChar() bolted for failed on new[], so bolt out of
> here.
>          if (cBuf == 0) {
>              throw runtime_error("XMLSocketApp::doreceive(bool& isComplete,
> vector<char>& ret_buf) "
>                  "MEMORY ALLOCATION ERROR BEFORE FINAL PARSE");
>          }
>
>          m_memBufIS->resetMemBufInputSource((const XMLByte *)cBuf, size);
>
>          if (m_defaultHandler != 0) {
>              m_parser->setContentHandler(m_defaultHandler);
>          }
>          if (m_errorHandler != 0) {
>              m_parser->setErrorHandler(m_errorHandler);
>          }
>          m_parser->parse(*m_memBufIS);
>          delete [] cBuf;
>      }
>
> See if you can spot the difference.  :-)
>
> I was under the impression that resetMemBufInputSource() would make its own
> internal copy of the buffer passed to it.  True?  I generally find the
> documentation for Xerces is lacking in these little detail member routines.
>