dynamic keyframes, textbox rework, andrea ffmpeg.opts, perpetual chkpt undo, lv2...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / filexml.C
index 065dce7db07758c48a49b9a6366a3dac0e0180e1..8914ff4498b29412500936913104e40740fd8aee 100644 (file)
@@ -73,9 +73,10 @@ XMLBuffer::~XMLBuffer()
        if( destroy ) delete [] bfr;
 }
 
-unsigned char *&XMLBuffer::demand(long len)
+int XMLBuffer::demand(long len)
 {
        if( len > bsz ) {
+               if( !destroy ) return 0;
                long sz = inp-bfr;
                len += sz/2 + BCTEXTLEN;
                unsigned char *np = new unsigned char[len];
@@ -85,13 +86,13 @@ unsigned char *&XMLBuffer::demand(long len)
                lmt = np + len;  bsz = len;
                delete [] bfr;   bfr = np;
        }
-       return bfr;
+       return 1;
 }
 
 int XMLBuffer::write(const char *bp, int len)
 {
-       if( !destroy && lmt-inp < len ) len = lmt-inp;
        if( len <= 0 ) return 0;
+       if( !destroy && lmt-inp < len ) len = lmt-inp;
        demand(otell()+len);
        memmove(inp,bp,len);
        inp += len;
@@ -108,6 +109,19 @@ int XMLBuffer::read(char *bp, int len)
        return len;
 }
 
+void XMLBuffer::copy_from(XMLBuffer *xbuf)
+{
+       if( bsz != xbuf->bsz ) { delete [] bfr;  bfr = 0; }
+       if( !bfr ) bfr = new unsigned char[bsz = xbuf->bsz];
+       lmt = bfr + bsz;
+       long ilen = xbuf->otell(), olen = xbuf->itell();
+       inp = pos(ilen);
+       outp = pos(olen);
+       if( ilen > 0 )
+               memmove(bfr, xbuf->bfr, ilen);
+       destroy = xbuf->destroy;
+}
+
 
 // Precision in base 10
 // for float is 6 significant figures
@@ -324,8 +338,12 @@ int XMLTag::read_tag(FileXML *xml)
                else
                        term = ' ';
                value_start = buf->itell()-1;
-               while( ch >= 0 && (ch!=term && ch!=right_delm && ch!='\n') )
+               while( ch >= 0 ) {
+// old edl bug work-around, allow nl in quoted string
+                       if( ch==term || ch==right_delm ) break;
+                       if( ch=='\n' && term!='\"' ) break;
                        ch = buf->next();
+               }
                if( ch < 0 ) EOB_RETURN();
                value_end = buf->itell()-1;
 // add property
@@ -358,11 +376,12 @@ FileXML::FileXML(int coded)
        output_length = 0;
        buffer = new XMLBuffer();
        set_coding(coded);
+       shared = 0;
 }
 
 FileXML::~FileXML()
 {
-       delete buffer;
+       if( !shared ) delete buffer;
        delete [] output;
 }
 
@@ -435,7 +454,7 @@ char* FileXML::get_data()
 }
 char* FileXML::string()
 {
-       return (char *)buffer->str();
+       return (char *)buffer->cstr();
 }
 
 long FileXML::length()
@@ -489,30 +508,29 @@ int FileXML::skip_tag()
        return 1;
 }
 
-int FileXML::read_data_until(const char *tag_end, char *out, int len, int skip)
+int FileXML::read_data_until(const char *tag_end, XMLBuffer *xbuf, int skip)
 {
        long ipos = buffer->itell();
-       int opos = 0, pos = -1;
-       int ch = buffer->next();
-       for( int olen=len-1; ch>=0 && opos<olen; ch=buffer->next() ) {
+       int pos = -1;
+       for( int ch=buffer->next(); ch>=0; ch=buffer->next() ) {
                if( pos < 0 ) { // looking for next tag
                        if( ch == left_delm ) {
                                ipos = buffer->itell()-1;
                                pos = 0;
                        }
                        else
-                               out[opos++] = ch;
+                               xbuf->next(ch);
                        continue;
                }
                // check for end of match
                if( !tag_end[pos] && ch == right_delm ) break;
                // if mismatched, copy prefix to out
                if( tag_end[pos] != ch ) {
-                       out[opos++] = left_delm;
-                       for( int i=0; i<pos && opos<olen; ++i )
-                               out[opos++] = tag_end[i];
-                       if( opos < olen ) out[opos++] = ch;
+                       xbuf->next(left_delm);
+                       for( int i=0; i<pos; ++i )
+                               xbuf->next(tag_end[i]);
                        pos = -1;
+                       xbuf->next(ch);
                        continue;
                }
                ++pos;
@@ -520,14 +538,14 @@ int FileXML::read_data_until(const char *tag_end, char *out, int len, int skip)
 // if end tag is reached, pos is left on the < of the end tag
        if( !skip && pos >= 0 && !tag_end[pos] )
                buffer->iseek(ipos);
-       return opos;
+       return xbuf->otell();
 }
 
-int FileXML::read_text_until(const char *tag_end, char *out, int len, int skip)
+int FileXML::read_text_until(const char *tag_end, XMLBuffer *xbuf, int skip)
 {
-       char data[len+1];
-       int opos = read_data_until(tag_end, data, len, skip);
-       decode(out, data, opos);
+       int len = read_data_until(tag_end, xbuf, skip);
+       char *cp = xbuf->cstr();
+       decode(cp, cp, len);
        return 0;
 }
 
@@ -610,30 +628,31 @@ int FileXML::get_coding()
        return coded;
 }
 
-int FileXML::set_shared_input(char *shared_string, long avail, int coded)
+int FileXML::set_shared_input(XMLBuffer *xbuf)
 {
        strcpy(this->filename, "");
        delete buffer;
-       buffer = new XMLBuffer(shared_string, avail, 0);
+       buffer = xbuf;
+       xbuf->iseek(0);
        set_coding(coded);
-        return 0;
+       shared = 1;
+       return 0;
 }
 
-int FileXML::set_shared_output(char *shared_string, long avail, int coded)
+int FileXML::set_shared_output(XMLBuffer *xbuf)
 {
        strcpy(this->filename, "");
        delete buffer;
-       buffer = new XMLBuffer(avail, shared_string, 0);
+       buffer = xbuf;
+       xbuf->oseek(0);
        set_coding(coded);
-        return 0;
+       shared = 1;
+       return 0;
 }
 
 
-
 // ================================ XML tag
 
-
-
 int XMLTag::title_is(const char *tp)
 {
        return !strcasecmp(title, tp) ? 1 : 0;
@@ -746,7 +765,8 @@ long XMLBuffer::encoded_length(const char *sp, int n)
 char *XMLBuffer::copy_data(char *bp, const char *sp, int n)
 {
        int len = n < 0 ? strlen(sp) : n;
-       memmove(bp,sp,len);
+       if( bp != sp )
+               memmove(bp,sp,len);
        bp[len] = 0;
        return bp;
 }