X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffilexml.C;h=8914ff4498b29412500936913104e40740fd8aee;hb=0d3917a4eda0344055badf0bd6e235c15c3b6cb8;hp=eccb503ac6143b1e9f5fa44c04236c89a87b670d;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/filexml.C b/cinelerra-5.1/cinelerra/filexml.C index eccb503a..8914ff44 100644 --- a/cinelerra-5.1/cinelerra/filexml.C +++ b/cinelerra-5.1/cinelerra/filexml.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include @@ -58,7 +58,7 @@ XMLBuffer::XMLBuffer(const char *buf, long buf_size, int del) destroy = del; } -XMLBuffer::XMLBuffer(long buf_size, const char *buf, int del) +XMLBuffer::XMLBuffer(long buf_size, char *buf, int del) { // writing bfr = (unsigned char *)buf; bsz = buf_size; @@ -73,24 +73,26 @@ XMLBuffer::~XMLBuffer() if( destroy ) delete [] bfr; } -unsigned char *&XMLBuffer::demand(long len) +int XMLBuffer::demand(long len) { if( len > bsz ) { - len += BCTEXTLEN; + if( !destroy ) return 0; + long sz = inp-bfr; + len += sz/2 + BCTEXTLEN; unsigned char *np = new unsigned char[len]; - if( inp > bfr ) memcpy(np,bfr,inp-bfr); + if( sz > 0 ) memcpy(np,bfr,sz); inp = np + (inp-bfr); outp = np + (outp-bfr); 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; @@ -107,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 @@ -277,7 +292,7 @@ int XMLTag::read_tag(FileXML *xml) // skip ws while( ch>=0 && ws(ch) ) ch = buf->next(); if( ch < 0 ) EOB_RETURN(); - + // read title ttl = buf->itell() - 1; for( int i=0; i=0; ++i, ch=buf->next() ) { @@ -323,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 @@ -357,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; } @@ -434,7 +454,7 @@ char* FileXML::get_data() } char* FileXML::string() { - return (char *)buffer->str(); + return (char *)buffer->cstr(); } long FileXML::length() @@ -472,45 +492,60 @@ int FileXML::read_tag() return tag.read_tag(this); } -int FileXML::read_data_until(const char *tag_end, char *out, int len) +int FileXML::skip_tag() +{ + char tag_title[sizeof(tag.title)]; + strcpy(tag_title, tag.title); + int n = 1; + while( !read_tag() ) { + if( tag.title[0] == tag_title[0] ) { + if( !strcasecmp(&tag_title[1], &tag.title[1]) ) ++n; + } + else if( tag.title[0] != '/' ) continue; + else if( strcasecmp(&tag_title[0], &tag.title[1]) ) continue; + else if( --n <= 0 ) return 0; + } + return 1; +} + +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 && oposnext() ) { + 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; inext(left_delm); + for( int i=0; inext(tag_end[i]); pos = -1; + xbuf->next(ch); continue; } ++pos; } // if end tag is reached, pos is left on the < of the end tag - if( pos >= 0 && !tag_end[pos] ) + 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 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); - decode(out, data, opos); + int len = read_data_until(tag_end, xbuf, skip); + char *cp = xbuf->cstr(); + decode(cp, cp, len); return 0; } @@ -542,11 +577,11 @@ int FileXML::write_to_file(FILE *file, const char *filename) int FileXML::read_from_file(const char *filename, int ignore_error) { - + strcpy(this->filename, filename); FILE *in = fopen(filename, "rb"); if( !in ) { - if(!ignore_error) + if(!ignore_error) eprintf("\"%s\" %m\n", filename); return 1; } @@ -593,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; @@ -729,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; }