void XMLFile::generate(const document& XMLDoc, iconvplus::MemoryBlock& Dump) { std::string encoding = iconvplus::wide_to_ascii(XMLDoc.getEncoding()); if (encoding.empty()) throw XMLError(XMLError::FILE_UNKNOWN_ENCODING); if (iconvplus::convert(iconvplus::MemoryBlock(XMLDoc.string()), Dump, "WCHAR_T", encoding)) throw XMLError(XMLError::FILE_UNKNOWN_ENCODING); if (!Dump.first) throw XMLError(XMLError::FILE_UNKNOWN_ENCODING); }
void XMLFile::save(const document& XMLDoc, const char *FileName) { iconvplus::MemoryBlock dumpOut; generate(XMLDoc, dumpOut); std::ofstream file(FileName, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); if (!file) throw XMLError(XMLError::FILE_CANT_OPEN); file.write(reinterpret_cast<const std::ifstream::char_type*>(dumpOut.second.get()), dumpOut.first); if (!file) throw XMLError(XMLError::FILE_CANT_WRITE); }
void ModelBuilder :: BuildGenerator( Model * model, const ALib::XMLElement * e ) { Generator * g = TagDictionary::Instance()->CreateGen( e ); if ( (! ALib::IsEmpty( g->Name() )) && model->FindGen( g->Name() )) { throw XMLError( "duplicate name " + ALib::SQuote( g->Name() ), e ); } model->AddGen( g ); }
void ModelBuilder :: AddDefine( Model * model, const ALib::XMLElement * e ) { RequireAttrs( e, AttrList( NAME_ATTRIB, VALUE_ATTRIB, 0 ) ); ForbidChildren( e ); string name = e->AttrValue( NAME_ATTRIB ); if ( ALib::IsEmpty( name ) ) { throw XMLError( "'name' attribute cannot be empty", e ); } string value = e->AttrValue( VALUE_ATTRIB ); model->AddDef( name, value ); }
document* XMLFile::load(const char *FileName) { std::ifstream file(FileName, std::ios_base::in | std::ios_base::binary); if (!file) throw XMLError(XMLError::FILE_CANT_OPEN); file.seekg(0, std::ios_base::end); std::ifstream::pos_type fileLength = file.tellg(); if (fileLength <= 3) throw XMLError(XMLError::FILE_TOO_SMALL); file.seekg(0, std::ios_base::beg); iconvplus::MemoryBlock dumpIn(fileLength, false); file.read(reinterpret_cast<std::ifstream::char_type*>(dumpIn.second.get()), fileLength); if (!file) throw XMLError(XMLError::FILE_CANT_READ); return load(dumpIn); }
// unique supports the following attributes: // order - usual stuff // fields - list of fields to consider for uniqueness // retry - number of time sto retry getting unique row DataSource * DSUnique :: FromXML( const ALib::XMLElement * e ) { RequireChildren( e ); AllowAttrs( e, AttrList( ORDER_ATTRIB,FIELDS_ATTRIB, RETRY_ATTRIB, 0 ) ); string fl = e->AttrValue( FIELDS_ATTRIB, "" ); FieldList cmpf( fl ); int retry = GetInt( e, RETRY_ATTRIB, ALib::Str( UNIQUE_RETRY) ); if ( retry < 0 ) { throw XMLError( ALib::SQuote( RETRY_ATTRIB ) + " cannot be negative", e ); } std::auto_ptr <DSUnique> c( new DSUnique( GetOrder( e ), cmpf , retry )); c->AddChildSources( e ); return c.release(); }
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) { if ( !file ) { SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } // Delete the existing data: Clear(); location.Clear(); // Get the file size, so we can pre-allocate the string. HUGE speed impact. long length = 0; fseek( file, 0, SEEK_END ); length = ftell( file ); fseek( file, 0, SEEK_SET ); // Strange case, but good to handle up front. if ( length <= 0 ) { SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } // If we have a file, assume it is all one big XML file, and read it in. // The document parser may decide the document ends sooner than the entire file, however. TIXML_STRING data; data.reserve( length ); // Subtle bug here. TinyXml did use fgets. But from the XML spec: // 2.11 End-of-Line Handling // <snip> // <quote> // ...the XML processor MUST behave as if it normalized all line breaks in external // parsed entities (including the document entity) on input, before parsing, by translating // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to // a single #xA character. // </quote> // // It is not clear fgets does that, and certainly isn't clear it works cross platform. // Generally, you expect fgets to translate from the convention of the OS to the c/unix // convention, and not work generally. /* while( fgets( buf, sizeof(buf), file ) ) { data += buf; } */ char* buf = new char[ length+1 ]; buf[0] = 0; if ( fread( buf, length, 1, file ) != 1 ) { delete [] buf; SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } const char* lastPos = buf; const char* p = buf; buf[length] = 0; while( *p ) { assert( p < (buf+length) ); if ( *p == 0xa ) { // Newline character. No special rules for this. Append all the characters // since the last string, and include the newline. data.append( lastPos, (p-lastPos+1) ); // append, include the newline ++p; // move past the newline lastPos = p; // and point to the new buffer (may be 0) assert( p <= (buf+length) ); } else if ( *p == 0xd ) { // Carriage return. Append what we have so far, then // handle moving forward in the buffer. if ( (p-lastPos) > 0 ) { data.append( lastPos, p-lastPos ); // do not add the CR } data += (char)0xa; // a proper newline if ( *(p+1) == 0xa ) { // Carriage return - new line sequence p += 2; lastPos = p; assert( p <= (buf+length) ); } else { // it was followed by something else...that is presumably characters again. ++p; lastPos = p; assert( p <= (buf+length) ); } } else { ++p; } } // Handle any left over characters. if ( p-lastPos ) { data.append( lastPos, p-lastPos ); } delete [] buf; buf = 0; Parse( data.c_str(), 0, encoding ); if ( XMLError() ) return false; else return true; }
document* XMLFile::load(const iconvplus::MemoryBlock& Dump) { if (Dump.first > 3) throw XMLError(XMLError::FILE_TOO_SMALL); std::string encoding; uint32_t BOM = *reinterpret_cast<const uint32_t*>(Dump.second.get()); if ((BOM & 0x00ffffff) == 0xbfbbef) { encoding = "UTF-8"; } else if (((BOM & 0x0000ffff) == 0xfffe) || (BOM == 0x003f003c)) { encoding = "UTF-16LE"; } else if (((BOM & 0x0000ffff) == 0xfeff) || (BOM == 0x3f003c00)) { encoding = "UTF-16BE"; } if (encoding.empty()) { if ((BOM & 0x0000ffff) == 0x3f3c)//8bit or UTF8 { size_t end = Dump.first; uint8_t *content = Dump.second.get(); char *gt = reinterpret_cast<char*>(memchr(content, '>', end)); if (gt) { *gt = '\0'; #ifdef _WIN32 char *encoding_start = strstr(reinterpret_cast<char*>(content), "encoding"); #else char *encoding_start = strcasestr(reinterpret_cast<char*>(content), "encoding"); #endif if (encoding_start) { size_t quot_open = strcspn(encoding_start, "\"'"); char quot_char = encoding_start[quot_open]; if (quot_char) { char *quot_close = strchr(encoding_start + quot_open + 1, quot_char); if (quot_close) encoding.assign(encoding_start + quot_open + 1, quot_close - (encoding_start + quot_open + 1)); } } *gt = '>'; } } } if (encoding.empty()) encoding = DEFAULT_ENCODING; iconvplus::MemoryBlock eDumpIn = Dump.copy(); iconvplus::MemoryBlock eDumpOut; if (iconvplus::convert(eDumpIn, eDumpOut, encoding, "WCHAR_T")) throw XMLError(XMLError::FILE_UNKNOWN_ENCODING); XMLParser parser; document *XMLDoc = parser.parse(eDumpOut); if (parser.getErrorCode()) { delete XMLDoc; throw XMLError(parser.getErrorCode(), parser.getPos(), parser.getLine(), parser.getChar()); } return XMLDoc; }