summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES77
-rwxr-xr-xCOPYING1
-rwxr-xr-xMakefile97
-rwxr-xr-xREADME295
-rwxr-xr-xbin/yhttpdbin0 -> 468081 bytes
-rwxr-xr-xconfigure33
-rw-r--r--etc/yhttpd.conf620
-rwxr-xr-xhtml/index.html37
-rwxr-xr-xhtml/style.css45
-rw-r--r--scripts/README2
-rwxr-xr-xscripts/buildnr.pl6
-rwxr-xr-xscripts/config.sh6
-rwxr-xr-xscripts/screen.sh2
-rwxr-xr-xscripts/setglobvals.pl2
-rwxr-xr-xscripts/stats.pl26
-rwxr-xr-xsrc/Makefile.in8
-rwxr-xr-xsrc/cli/cli.cpp443
-rwxr-xr-xsrc/cli/cli.h30
-rwxr-xr-xsrc/conf/conf.cpp198
-rwxr-xr-xsrc/conf/conf.h23
-rwxr-xr-xsrc/configure34
-rw-r--r--src/contrib/README4
-rw-r--r--src/contrib/xml/README2
-rw-r--r--src/contrib/xml/tinyxml.cpp1679
-rw-r--r--src/contrib/xml/tinyxml.h2242
-rw-r--r--src/contrib/xml/tinyxmlerror.cpp44
-rw-r--r--src/contrib/xml/tinyxmlparser.cpp2684
-rwxr-xr-xsrc/glob.h58
-rwxr-xr-xsrc/html.cpp163
-rwxr-xr-xsrc/html.h45
-rwxr-xr-xsrc/incl.h6
-rwxr-xr-xsrc/logd.cpp182
-rwxr-xr-xsrc/logd.h41
-rwxr-xr-xsrc/main.cpp193
-rw-r--r--src/maps/hmap.h6
-rw-r--r--src/maps/hmap.tmpl11
-rw-r--r--src/maps/mtools.h6
-rw-r--r--src/maps/mtools.tmpl5
-rw-r--r--src/maps/smap.h1
-rw-r--r--src/maps/smap.tmpl8
-rwxr-xr-xsrc/modl.cpp158
-rwxr-xr-xsrc/modl.h33
-rw-r--r--[-rwxr-xr-x]src/msgs.h45
-rwxr-xr-xsrc/name.cpp34
-rwxr-xr-xsrc/name.h20
-rwxr-xr-xsrc/ncur/menu.cpp149
-rwxr-xr-xsrc/ncur/menu.h27
-rwxr-xr-xsrc/ncur/ncur.cpp359
-rwxr-xr-xsrc/ncur/ncur.h50
-rwxr-xr-xsrc/reqp.cpp476
-rwxr-xr-xsrc/reqp.h60
-rwxr-xr-xsrc/sock/sock.cpp390
-rwxr-xr-xsrc/sock/sock.h80
-rw-r--r--src/stats.cpp169
-rw-r--r--src/stats.h31
-rwxr-xr-xsrc/thrd/pool.cpp315
-rwxr-xr-xsrc/thrd/pool.h108
-rw-r--r--src/thrd/thro.cpp23
-rw-r--r--src/thrd/thro.h26
-rwxr-xr-xsrc/time/timo.cpp24
-rwxr-xr-xsrc/time/timo.h12
-rwxr-xr-xsrc/time/timr.cpp198
-rwxr-xr-xsrc/time/timr.h81
-rw-r--r--src/tool/dir.cpp44
-rw-r--r--src/tool/dir.h26
-rw-r--r--src/tool/tool.cpp251
-rw-r--r--src/tool/tool.h96
-rwxr-xr-xsrc/wrap.cpp22
-rwxr-xr-xsrc/wrap.h101
69 files changed, 6084 insertions, 6689 deletions
diff --git a/CHANGES b/CHANGES
index 4bf7178..21919f7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,75 +1,4 @@
-Changes from 0.7.6-RELEASE to 0.7.7-RELEASE
-- Major code cleanup
-- Bugfix in /col
-- Bugfix in gcol #1 (destroy session also if no database is used)
-- Bugfix in gcol #2 (now runs each hour not once a day)
-- Renew the style.css and stream.html
-
-Changes from 0.7.5-RELEASE to 0.7.6-RELEASE
-- Removed the old hash maps and included the SGI C++ STL extenstion
- hash_map.
-
-Changes from 0.7.4.1-RELEASE to 0.7.5-RELEASE
-- Garbage collector will now run once a hour rather than each ten minutes.
-- Dynamic thread pool improvements.
-- Removed equiv-http-refresh meta tag from the online list.
-- Minor bugfix in the /topic command.
-- Implemented "User list"
-
-Changes from 0.7.4-RELEASE to 0.7.4.1-RELEASE:
-- Dynamic thread pool bugfix (dead lock)
-
-Changes from 0.7.3-RELEASE to 0.7.4-RELEASE:
-- Code cleanup.
-- Made the thread pool increasing dynamic.
-- Added some thread pool optimazions.
-- Added some more ${MAKE} vars to the Makefiles.
-- Added Content-length to the HTTPD header.
-- Added the !command to the command line interface.
-- Added Content-type text/plain.
-- Added scrolling checkbox to input.html
-- Removed modl from yhttpd. Dynamic modules are not needed in yhttpd yet.
-- Improved session engine.
-- Fixed auto logout bug.
-- Fixed newline bug (one \n too much for each html template)
-- Logging can now be completely disabled.
-
-Changes from 0.7.2 to 0.7.3-RELEASE:
-- Added FreeBSD 5.3-RELEASE support.
-- Added chat.enableguest option.
-- Added the /all command (Global system message)
-- Renamed the /getstatus command into /about.
-- Fixed the &-bug (& should be allowed in messages). \AND is now a
- synonym for & too.
-- Fixed the /msg bug (In /msg the string replacer should be activated).
-- Fixed logging bug (do not log any timestamps if there are no messages).
-
-Changes from 0.7.1 to 0.7.2-RELEASE:
-New features:
-- /morph
-- Added the new standard html template design.
-Bugfixes:
-- /away prints a . instead of a : if no away reason is given.
-- /ko message was wrong. Displayed not room name of the user to be kicked out.
-- /invisible command displayed wrong private messages.
-- /getstatus had no help text.
-- /msg and /s should now print the system time if printalwaystime == true.
-- Added a blank to the /uptime message.
-- /topic now prints the topic in the user's color.
-- Fixed some typos.
-
-Changes from 0.7.0 to 0.7.1-RELEASE:
-- Added ${MAKE} to the config file because some Linux distros dont use
- the "gmake" command for GNU make but just "make"! Modified the
- configure script to generate a make.version file.
-- Removed some typos from the ychat.conf.
-- Fixed the auto away message. This one will be posted in the room
- as public rather than only private to the auto-away-user.
-- Fixed some documentation stuff for yhttpd because yhttpd does not
- need MySQL at all.
-- Added the chat.maxlength.word option.
-
-Changes from 0.6 to 0.7.0-RELEASE:
+Changes from 0.6 to 0.7 RELEASE
- Better stability
- Better performance (using more hmaps)
- HTML color switcher menu
@@ -89,9 +18,9 @@ Changes from 0.6 to 0.7.0-RELEASE:
- Added admin CLI (Command Line Interface) mode
- Added memory rusage history which tracks memory usage for the last 10 days
- Added HTTP POST request parsing
-- Made yChat more modular so yhttpd can be extracted from it (scripts/makeyhttpd.pl)
+- Made yhttpd more modular so yhttpd can be extracted from it (scripts/makeyhttpd.pl)
- Added CGI support
- Rewrote big parts of the Makefiles and the configure scripts
- Made it compatible to GNU G++ 3.4, 3.3, 3.2 and 3.1 (3.0 and earlier does not work)
-- XML based configuration file (ychat.conf)
+- XML based configuration file (yhttpd.conf)
- Added default operator option: chat.defaultop
diff --git a/COPYING b/COPYING
index a43ea21..27058a5 100755
--- a/COPYING
+++ b/COPYING
@@ -106,7 +106,6 @@ above, provided that you also meet all of these conditions:
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
diff --git a/Makefile b/Makefile
index e0b6e07..ff97421 100755
--- a/Makefile
+++ b/Makefile
@@ -1,84 +1,81 @@
-MAKE=`tail -n 1 make.version`
PREFIX=`grep "define PREFIX" src/glob.h | cut -d'"' -f2`
-all: version base modules version
- @echo "Now edit the ychat.conf and run ychat!"
+all: base modules version
+ @echo "Now edit the yhttpd.conf and run yhttpd!"
@echo "The config file is searched in the following order:"
- @echo " ./ychat.conf "
- @echo " ~/.ychat/ychat.conf "
- @echo " ./etc/ychat.conf "
- @echo " /etc/ychat.conf "
- @echo " $(PREFIX)/etc/ychat.conf "
- @echo If you want to help the yChat project please run gmake mail
- @echo so that the developers receive an email about the platform
- @echo being used.
-mail:
- @echo "VERSION:" > mail.tmp
- @${MAKE} version >> mail.tmp
- @echo >> mail.tmp
- @echo "UNAME:" >> mail.tmp
- @uname -a >> mail.tmp
- @echo >> mail.tmp
- @echo "DATE:" >> mail.tmp
- @date >> mail.tmp
- @echo >> mail.tmp
- @echo "COMPILER AND MAKE:" >> mail.tmp
- @cat g++.version make.version >> mail.tmp
- @cat mail.tmp | mail -s "Successfull build of yChat" successfullbuild@yhttpd.org
- @rm -f mail.tmp
-install: deinstall
+ @echo " ./yhttpd.conf "
+ @echo " ~/.yhttpd/yhttpd.conf "
+ @echo " ./etc/yhttpd.conf "
+ @echo " /etc/yhttpd.conf "
+ @echo " $(PREFIX)/etc/yhttpd.conf "
+install: deinstall
+ @echo "Instaling yhttpd to $(PREFIX)"
+ @cp bin/yhttpd $(PREFIX)/bin
+ @if ! test -d $(PREFIX)/lib/yhttpd; then mkdir -p $(PREFIX)/lib/yhttpd; fi
+ @if ! test -d $(PREFIX)/share/yhttpd/log/rooms; then mkdir -p $(PREFIX)/share/yhttpd/log/rooms; fi
+ @if ! test -d $(PREFIX)/etc; then mkdir $(PREFIX)/etc; fi
+ @if test -d mods; then cp -Rp mods $(PREFIX)/lib/yhttpd/mods; fi
+ @cp -Rp lang $(PREFIX)/share/yhttpd/lang
+ @if test -f $(PREFIX)/etc/yhttpd.conf; then mv $(PREFIX)/etc/yhttpd.conf $(PREFIX)/etc/yhttpd.conf.bak; fi
+ @cp etc/yhttpd.conf etc/yhttpd.conf.tmp
+ @sed "s#mods/#$(PREFIX)/lib/yhttpd/mods/#" etc/yhttpd.conf.tmp > etc/yhttpd.conf.tmp.2 && mv etc/yhttpd.conf.tmp.2 etc/yhttpd.conf.tmp
+ @sed "s#\"log/#\"$(PREFIX)/share/yhttpd/log/#" etc/yhttpd.conf.tmp > etc/yhttpd.conf.tmp.2 && mv etc/yhttpd.conf.tmp.2 etc/yhttpd.conf.tmp
+ @sed "s#LANGUAGE_DIR=\"lang/#LANGUAGE_DIR=\"$(PREFIX)/share/yhttpd/lang/#" etc/yhttpd.conf.tmp > etc/yhttpd.conf.tmp.2 && mv etc/yhttpd.conf.tmp.2 etc/yhttpd.conf.tmp
+ @mv etc/yhttpd.conf.tmp $(PREFIX)/etc/yhttpd.conf
+ @echo "yhttpd configuration file can be found under"
+ @echo " $(PREFIX)/etc/yhttpd.conf"
+ @echo "Copy it to ~/.yhttpd/yhttpd.conf to use local settings :-)"
+ @echo "Be sure that $(PREFIX)/share/yhttpd/logs is writable by your user or modify "
+ @echo "logging dirs in the yhttpd.conf to a local directory."
+ @echo "The most secure would be an additional user 'yhttpd'!"
uninstall: deinstall
deinstall:
- @echo Install/deinstall is not supported!
- @echo Start yChat with ./bin/ychat instead!
- @exit 1
+ @echo "Deinstalling yhttpd from $(PREFIX)"
+ @if test -f $(PREFIX)/bin/yhttpd; then rm -f $(PREFIX)/bin/yhttpd; fi
+ @if test -d $(PREFIX)/lib/yhttpd; then rm -Rf $(PREFIX)/lib/yhttpd; fi
+ @if test -d $(PREFIX)/share/yhttpd; then rm -Rf $(PREFIX)/share/yhttpd; fi
+ @echo "Done. Please remove manually $(PREFIX)/etc/yhttpd.conf to complete"
modules:
- @if test -d ./src/mods; then ${MAKE} -C ./src/mods; fi
+ @if test -d ./src/mods; then gmake -C ./src/mods; fi
clean_modules:
- @if test -d ./src/mods; then ${MAKE} -C ./src/mods clean; fi
+ @if test -d ./src/mods; then gmake -C ./src/mods clean; fi
base:
- @if test -f bin/ychat; then echo "Backing up old binary";if test -f bin/ychat.old; then rm -f bin/ychat.old; fi; mv bin/ychat bin/ychat.old; fi
+ @if test -f bin/yhttpd; then echo "Backing up old binary";if test -f bin/yhttpd.old; then rm -f bin/yhttpd.old; fi; mv bin/yhttpd bin/yhttpd.old; fi
@perl ./scripts/buildnr.pl
@perl ./scripts/setglobvals.pl
- @${MAKE} -C ./src
+ @gmake -C ./src
clean_base:
- @${MAKE} -C ./src clean
+ @gmake -C ./src clean
stats:
@perl scripts/stats.pl
run:
- ./bin/ychat
+ ./bin/yhttpd
base_start: base
- ./bin/ychat
+ ./bin/yhttpd
start: base modules
- ./bin/ychat
+ ./bin/yhttpd
gpl:
@more COPYING
-#//<<*
-yhttpdbase:
- @perl scripts/makeyhttpd.pl || echo "You need to have perl to do this!"
- @echo yhttpd code base has been generated in ../yhttpd
-#//*>>
clean: clean_base clean_modules
help:
- @echo "You may run ${MAKE} with the following parameters:"
- @grep "^ ${MAKE} " README
- @echo "For more questions read the README file or contact mail@ychat.org!"
+ @echo "You may run gmake with the following parameters:"
+ @grep "^ gmake " README
+ @echo "For more questions read the README file or contact mail@yhttpd.org!"
setup:
@./configure
- @${MAKE}
+ @gmake
config:
@sh -c "scripts/config.sh"
- @echo If you run ${MAKE} config from the command line then you may need
+ @echo If you run gmake config from the command line then you may need
@echo to rerun ./configure and recompile all now!
mrproper: clean
@if test -f src/glob.h.org; then mv -f src/glob.h.org src/glob.h;fi
@if test -f g++.version; then rm -f g++.version; fi
- @if test -f make.version; then rm -f make.version; fi
@if test -f src/Makefile; then rm -f src/Makefile; fi
@if test -d src/mods; then find src/mods/*/ -name Makefile | xargs rm -f; fi
@find . -name "*.add" | xargs rm -f
@ls | grep core | xargs rm -f
version:
- @./scripts/version.sh
+ @echo "`grep VERSION src/msgs.h | cut -d'"' -f2`-`grep BRANCH src/msgs.h| cut -d'"' -f2` Build `grep BUILD src/msgs.h| cut -d' ' -f3`"
debug:
- @gdb bin/ychat ychat.core
+ @gdb bin/yhttpd yhttpd.core
diff --git a/README b/README
index 038c4f6..72410d3 100755
--- a/README
+++ b/README
@@ -1,8 +1,9 @@
-yChat; Homepage: www.yChat.org; Version 0.7.7-RELEASE
+yhttpd; Homepage: www.yhttpd.org; Version 0.7-RELEASE
Copyright (C) 2003 Paul C. Buetow, Volker Richter
-Copyright (C) 2004, 2005 Paul C. Buetow
+Copyright (C) 2004 Paul C. Buetow
-----------------------------------------------------------------
+
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
@@ -18,131 +19,20 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-----------------------------------------------------------------
-YCHAT TABLE OF CONTENTS:
+YHTTPD TABLE OF CONTENTS:
-0.0.0 YCHAT FEATURES //<<
1.0.0 REQUIREMENTS
1.1.0 TESTED PLATFORMS
1.2.0 IMPORTANT NOTICES
-1.3.0 HOW TO OBTAIN YCHAT
+1.3.0 HOW TO OBTAIN YHTTPD
1.3.1 INSTALLATION
1.3.2 INSTALLATION QUICK-START
-1.3.3 MYSQL SETUP //<<
-1.4.0 HOW TO USE SCREEN WITH YCHAT
+1.4.0 HOW TO USE SCREEN WITH YHTTPD
1.5.0 CUSTOMIZATION
1.6.0 FILES
1.7.0 WRITING BUG REPORTS
1.8.0 CONTACT
-1.9.0 YHTTPD CODE BASE GENERATION //<<
-
-//<<*
-0.0.0 YCHAT FEATURES
-
-- Its free & portable -
-yChat is developed under the GNU general public license and is based on GNU
-tools (gcc, gmake), other open source library stuff (such as libncurses etc.)
-and should run on any POSIX capable operating system (such as all Linux based
-systems, FreeBSD, NetBSD, OpenBSD and other BSD-Systems and on UNICES like
-IRIX, HP-UX, Solaris etc.).
-
-- There is no need for special chat clients -
-yChat is web based, that means clients may only connect to the chat server
-with an normal web browser such as Microsoft Internet Explorer or any Gecko-
-Engine powerd browsers like Mozilla, Firefox, Camino etc.
-
-- It has features of a real HTTP webserver -
-yChat runs completely stand alone and does not need another webserver to build
-on like Apache and does not need to be run via any kind of CGI. yChat creates
-its own socket on a customized port (standard port: 2000) and seems to be a full
-featured HTTP web server to the clients (web browsers).
-
-The yChat code base can be converted to an yhttpd code base automaticaly. yhttpd
-is the webserver subset of yChat which runs completely stand alone and provides
-normal websites to the net. It also supports Common Gateway Interface (CGI)
-scripting.
-
-- Its fast and secure -
-yChat is written in C++ which is faster than any Java based Chat-Server or any
-server written in a scripting language like PHP, Python or Perl. As the
-internal data structures hash maps are used to garuantee searching certain
-values in O(1) amount of time. If a hash maps gets full, it will be rehashed.
-Currently, yChat has been measured providing over 1000 hits/requests per second
-on a FreeBSD based server box while using less than 2% of CPU usage
-on a Athlon XP 1900+. Performance seems to be limited by your bandwith only.
-Also, each user gets its own session id (random string) with a standard length
-of 50 chars to authenticate each logged in user. The length of the session id
-can be redefined as well. Also, the session id will get md5-hashed optionally
-so thats even harder to reverse engineering the session ids of other users.
-
-- Its HTML template based and easy to customize via XML based configuration -
-All HTML sites are predefined as HTML-Template files and can be easily modified
-to use with an customized web design. Also, a lot of yChat preferences can be
-set in the main configuration file (ychat.conf). ychat.conf is completely written
-in XML 1.0 which makes it easier to use the configuration options in programs of
-3rd persons which may want to write some usefull tools for yChat.
-yChat caches all HTML and web images to improve overall performance. If needed, the
-cache can be cleared to recache new versions of the template files.
-
-- Its language template based -
-The administrator can easily create a new language in which all system messages
-appear to the Chat-User. The predefined languages is english but others can be
-added easily. The language can be edited in the XML based configuration file.
-
-- MySQL based database -
-Registered users are stored in a MySQL database. C++ Programmers may feel free
-to replace the database wrapper class (data.h) with another database routines
-to use other databases such as PostgreSQL, SQLite or a text based database etc.
-If wished, you can disable database support in the pre-compile options.
-
-- It has an administration interface -
-yChat includes an ncurses based administration interface which tracks some
-interesting statistics and system messages and enables you to do certain
-administrative tasks. In addition, you can switch to the CLI (command line
-interface) mode of the administration interface in order to be provided with
-more available functions (like keeping track of the current system usage etc.).
-If you dont like ncurses and/or the CLI you can disable both options in the pre-
-compile options.
-
-- It has logging capabilities -
-The logging manager keeps track to all yChat system messages (such as users
-wich log in and out, modules which are loaded, MySQL queries etc.). Also, an
-Apache-Style combined log file format is created by yChat (you can parse this
-logfile with any Apache logfile parser like awstats etc.). And last but not
-least, all public messages of all available rooms will be logged to disk as
-well . To improve performance, you can define the logging puffer (standardly
-new logs will be written to disk after each 20 lines). If you want to log
-everything immediately, you can reset this option to 1 in ychat.conf.
-
-- Its modular through own command and dynamic HTML engine -
-All chat commands are realized through dynamic loadable module files which can
-be recompiled and reloaded without restarting the whole yChat server. Also
-HTML-Sites with certain tasks can be compiled as a module like
-mods/html/yc_register.so, mods/html/yc_options.so and mods/html/yc_colors.so
-etc. so you can also program your dynamic yChat websites in C++.
-
-- Its multi threaded (POSIX threads) -
-There is only one main process which spawns several threads, each for its own
-unique task. For example one thread is used to handle the socket manager which
-waits for incoming TCP/IP requests, another thread schedules the system timer
-which proves if clients are still active or frees not needed memory in certain
-time intervals (see also "Garbage collector"). Also, each Chat-User gets it own
-thread. There is no need of memory wastage by creating for each task a new
-process. All User-Threads are managed by a thread pool to avoid CPU wastage
-creating every time a new thread by reusing thread objects which have done its
-jobs already and have been readded into the queue of the thread pool. The
-standard sizes of the queue and the total pool size can be set in ychat.conf.
-
-- Its using a smart garbage collection engine -
-All users and rooms which dont have to be kept in the main memory (because the
-user has logged out or the room has been destroyed because it was empty) will
-not be deleted immediately but be placed for about 10 minutes in the yChat
-garbage collector. Each time a new room is created the systems checks the
-garbage to reuse an inactive room object. If a certain user wants to log in, the
-system checks if he is already present in the garbage collector. If yes, he will
-be reactivated without wasting expensive database queries to fetch the user's
-options. This improves overall performance on heavily loaded yChat servers if a
-lot of user and room objects are created and destroyed frequently.
-//*>>
+
1.0.0 REQUIREMENTS:
@@ -152,25 +42,18 @@ lot of user and room objects are created and destroyed frequently.
- GNU make 3.80 (gmake) or higher
If you dont have a gmake executable but make is gnu make then you need
to add a symlink or alias from gmake to make.
- yChat Makefiles only have been tested with GNU make and may not work with
+ yhttpd Makefiles only have been tested with GNU make and may not work with
other make versions.
-- SGI STL extension
- Includes ext/hash_map which may be already default on every Linux distro.
- On *BSD you have to install it first before compiling. On FreeBSD
- /usr/ports/devel/stlport is your friend.
-
-//<<*
- mysql-client 4.x (3.x may do too but is not supported)
Includes libmysqlclient and the mysql.h header files.
-//*>>
- ncurses 5.x
Includes libncurses and the ncurses.h header files.
- Screen
- Only needed if yChat should run in background with
- ncurses or CLI enabled.
+ Only needed if yhttpd should run in background with
+ ncurses enabled.
- Perl 5.x
Is needed for some scripts. Is not needed if you use precompiled binaries.
@@ -181,16 +64,13 @@ The following platforms have been tested with success. If you find out that
a listed platform did not work at all please contact me:
Operating system (arch) GNU G++ GNU make
-- FreeBSD 5.3-RELEASE (i386) 3.4.2 3.80
- FreeBSD 5.2.1-RELEASE (i386) 3.3.3 3.80
-- FreeBSD 4.10-RELEASE (i386) 3.4.1 3.80
- FreeBSD 4.9-RELEASE (i386) 3.3.4 3.80
-- Gentoo Linux 2004 (i386) 3.3.2 3.80
-- OpenBSD 3.6 SMP (i386) 3.3.2 3.80
-- Red Hat Linux 8.0 SMP (i386) 3.2-7 3.79
+- FreeBSD 4.10-RELEASE (i386) 3.4.1 3.80
+- Gentoo Linux 2004.2 (i386) 3.3.2 3.80
+- OpenBSD 3.6 MP (i386) 3.3.2 3.80
- Slackware Linux 10.0 (i386) 3.4.0 3.80
-- SUSE Linux 9.0 (i386) 3.3.1 3.80
-- SUSE Linux 8.1 (i386) 3.2 3.79.1
+- SUSE Linux 8.0, G (i386) 3.3.1 3.80
Other platforms like Linux based systems, other BSD-Systems or UNICES
are very likely to work too.
@@ -200,23 +80,23 @@ are very likely to work too.
Before you compile the source you have to be sure to use at least GCC
version 3.1 with pthreads enabled. ( Type gcc -v to check it ).
GCC 2.95 and 3.0 did not work while testing and WON'T BE SUPPORTED!
-If you like to support yChat, please write us an email and tell what
-you can/like/would help ;-]. Please also take a look at the yChat
-homepage which is located at http://www.yChat.org.
+If you like to support yhttpd++, please write us an email and tell what
+you can/like/would help ;-]. Please also take a look at the yhttpd++
+homepage which is located at http://www.yhttpd.org.
-1.3.0 HOW TO OBTAIN YCHAT:
+1.3.0 HOW TO OBTAIN YHTTPD++:
-yChat can be downloaded as a source package or through CVS.
+yhttpd can be downloaded as a source package or through CVS.
-The packages are located at http://www.yChat.org -> Sourcecode ->
-Packages or go to http://pub.buetow.org/yChat/CPP-yChat .
+The packages are located at http://www.yhttpd.org -> Sourcecode ->
+Packages or go to http://pub.buetow.org/yhttpd/CPP-yhttpd .
For CVS download type:
cvs -d:pserver:anonymous@buetow.org:/usr/home/cvs/cvsroot login
( You will be asked for a password. Use "just enter" ).
-vs -z3 -d:pserver:anonymous@buetow.org:/usr/home/cvs/cvsroot co ychat
+vs -z3 -d:pserver:anonymous@buetow.org:/usr/home/cvs/cvsroot co yhttpd
( The sources will be copied into your local folder )
cvs -d:pserver:anonymous@buetow.org:/usr/home/cvs/cvsroot logout
@@ -227,44 +107,37 @@ Now you may continue with the installation.
1.3.1 INSTALLATION:
Invoke "./configure". Afterwards you will get prompted with the before-compile
-options of yChat. After choosing those options you are ready to type "gmake"
-afterwards. See below what gmake is doing.
+options of yhttpd. After choosing those options you are ready to type "gmake"
+afterwards.
-//<<*
-If you have choosen MySQL database support, then take a look at section 1.3.2
-how to setup a valid database table. Be also sure to enter the valid MySQL
-accessing data in the yChat configuration file which is normally located in
-the etc/ychat.conf file if not changed by you with the yChat configurator.
-//*>>
You may also invoke gmake with the following options (the PREFIX can be set
-in the yChat configurator which will be launched by the top configure script
+in the yhttpd configurator which will be launched by the top configure script
or gmake config):
- gmake or gmake all (compiles everything, also modules and runs "gmake mail")
+ gmake or gmake all (compiles everything, also modules)
gmake base (only compiles the base)
gmake base_start (only compiles the base and starts the server)
gmake clean (cleans everything)
gmake clean_base (only cleans the base obj and rpo files)
gmake clean_modules (only cleans the modules .so files)
- gmake config (runs yChat configurator)
+ gmake config (runs yhttpd configurator)
+ gmake deinstall (deinstalls yhttpd from PREFIX)
gmake gpl (shows the GNU General Public License)
- gmake help (shows all available ychat gmake targets)
- gmake mail (sends a mail to the yChat developers containing build opts.)
+ gmake help (shows all available yhttpd gmake targets)
+ gmake install (installs yhttpd to PREFIX)
gmake modules (only compiles modules)
gmake mrproper (same as gmake clean plus removing all temp files)
gmake setup (runs all configure scripts and afterwards gmake all)
gmake start (compiles everything and starts the server)
- gmake stats (generates ychat statistics)
- gmake version (shows the current version of yChat)
-//<<*
- gmake yhttpdbase (generates an yhttpd code base)
-//*>> (See section 1.9 to read about this marks)
+ gmake stats (generates yhttpd statistics)
+ gmake uninstall (same as deinstall)
+ gmake version (shows the current version of yhttpd)
Example: "gmake all install clean" compiles everything, installs it to PREFIX
and cleans the source directories.
-Now its time to run the server with ./bin/ychat.
+Now its time to run the server with ./bin/yhttpd.
Aferwards point your webbrowser to http://yourip:port !
@@ -272,54 +145,25 @@ Aferwards point your webbrowser to http://yourip:port !
1.3.2 INSTALLATION QUICK START:
-If you in hury, then you may just type gmake setup. In the yChat configurator
-you may just choose all the default values. If done, yChat will get compiled
-and is ready to run with ./bin/ychat!
-
+If you in hury, then you may just type gmake setup. In the yhttpd configurator
+you may just choose all the default values. If done, yhttpd will get compiled
+and is ready to run with ./bin/yhttpd!
-//<<*
-1.3.3 MYSQL SETUP
-If you chose to use MySQL database support you have to create a valid database
-to use with yChat.
+1.4.0 HOW TO USE SCREEN WITH YHTTPD:
-Create a new MySQL database called 'ychat' and type the following command into
-a MySQL command line client of your choice:
-
-USE ychat
-CREATE TABLE `user` (
- `uid` int(10) NOT NULL auto_increment,
- `nick` varchar(30) NOT NULL default '',
- `password` varchar(30) NOT NULL default '',
- `color1` varchar(30),
- `color2` varchar(30),
- `email` varchar(50) default '-',
- `registerdate` varchar(30) default '-',
- `logincounter` varchar(10) default '0',
- `status` char(1) default '3',
- PRIMARY KEY (`uid`),
- KEY `uid` (`uid`)
-) TYPE=MyISAM;
-GRANT ALL PRIVILEGES ON ychat.* to ychat@localhost IDENTIFIED BY "yctest";
-
-This database uses the default MySQL access informations which are stored in the
-ychat.conf file.
-//*>>
-
-1.4.0 HOW TO USE SCREEN WITH YCHAT:
-
-If you are running yChat in ncurses mode you might want to install
+If you are running yhttpd in ncurses mode you might want to install
the tool which is called "screen". This will enable you putting the
ncurses interface into the background, closing the terminal session
and reusing the interface later through another terminal.
Just do:
- screen -S ychat ./bin/ychat ( creates a new session and starts yChat in it )
- ctrl+d+a ( will detach the yChat session )
+ screen -S yhttpd ./bin/yhttpd ( creates a new session and starts yhttpd in it )
+ ctrl+d+a ( will detach the yhttpd session )
( closing the terminal )
( opening a new terminal )
- screen -r ychat ( will return you to the yChat process )
+ screen -r yhttpd ( will return you to the yhttpd process )
Screen will terminate automaticaly if all processes in its sessions are
terminated.
@@ -328,25 +172,25 @@ For a closer look read the screen manual page ( man screen ).
1.5.0 CUSTOMIZATION:
-If you like to customize the design/layout/language of yChat, you will have
+If you like to customize the design/layout/language of yhttpd, you will have
to edit src/msgs.h and src/glob.h before you compile the sources. Afterwards
you can change the html-template files which are placed in the html/
subdirectory and the language-templates which are placed in the XML config
-file (etc/ychat.conf).
+file (etc/yhttpd.conf).
Notice, that you dont have to edit the src/glob.h file by hand any more, its
already done by the top ./configure script for you.
-You can edit the etc/ychat.conf to fit your needs. If you dont want to change
-the config file, then you also can use ychat start parameters.
+You can edit the etc/yhttpd.conf to fit your needs. If you dont want to change
+the config file, then you also can use yhttpd start parameters.
-Exmpl: ./bin/ychat -o chat.database.password secretpassword
+Exmpl: ./bin/yhttpd -o chat.database.password secretpassword
You can also use multiple words for a specific option.
-Exmpl: ./bin/ychat -o ychat.version "word1 word2 word3"
+Exmpl: ./bin/yhttpd -o yhttpd.version "word1 word2 word3"
-will overwrite the default database password value of the ychat.conf. You can
+will overwrite the default database password value of the yhttpd.conf. You can
do this with every configuration element by adding several -o option value
arguments to the start command.
@@ -361,16 +205,16 @@ user never wont read them, only the administrator will get to see them ).
1.6.0 FILES:
-etc/ychat.conf - The yChat configuration file
+etc/yhttpd.conf - The yhttpd configuration file
html/* - The html template files
-src/* - The yChat base sources
+src/* - The yhttpd base sources
src/mods/* - The dynamic loadable modules sources
scripts/* - Some nice scripts needed for building & co.
-The following is created by building yChat:
-obj/* - The object files of the compiled yChat base
+The following is created by building yhttpd:
+obj/* - The object files of the compiled yhttpd base
mods/* - The compiled dynamic loadable modules
-bin/ychat - The yChat binary (linked by the object files)
+bin/yhttpd - The yhttpd binary (linked by the object files)
Customizable source files (if changed you need to run gmake clean all)
src/glob.h - Contains some global building options
@@ -381,29 +225,29 @@ src/msgs.h - Defines some server side messages
How to submit a good bug report?
-Send them to Bug@yChat.org.
+Send them to Bug@yhttpd.org.
First you should give the following information:
-- yChat version, if CVS (or devel. tarball) then which day?
+- yhttpd version, if CVS (or devel. tarball) then which day?
- operating system / distribution and it's version
- when did it crash? did you do something? can you reproduce the crash?
-Getting backtrace of the crash also helps a lot, especially if yChat crashes
+Getting backtrace of the crash also helps a lot, especially if yhttpd crashes
randomly. If after crash you see text:
"segmentation fault (core dumped)"
-It writes a file named "core" or "ychat.core" depending on your OS to directory
-where you started yChat. If it doesn't print the "(core dumped)" or you can't
+It writes a file named "core" or "yhttpd.core" depending on your OS to directory
+where you started yhttpd. If it doesn't print the "(core dumped)" or you can't
find the core file, you'll have to raise the limit for max. core file size
-before running yChat. To do this, say:
+before running yhttpd. To do this, say:
ulimit -c unlimited
So, if you have the core file and GNU debugger (gdb), you can get the
backtrace with:
- gdb ./bin/ychat ychat.core
+ gdb ./bin/yhttpd yhttpd.core
bt
Paste all the lines starting from line having #0 at the beginning.
@@ -423,10 +267,10 @@ Here's an example session:
#5 0x281d44ae in _thread_start () from /usr/lib/libc_r.so.5
(gdb)
-If you dont get such a gdb output, you need to recompile the yChat using
+If you dont get such a gdb output, you need to recompile the yhttpd using
debuggig symbols. You can do it this way:
-cd ychat
+cd yhttpd
gmake mrproper
./configure -g3 -ggdb
gmake start
@@ -436,12 +280,12 @@ gmake start
You may contact us through the following addresses:
- Homepage
- The yChat homepage is located at http://www.yChat.org
+ The yhttpd homepage is located at http://www.yhttpd.org
- E-Mail
- Paul C. Buetow: Snooper at yChat point org ( core developer )
- Volker Richter: Rover at yChat dot org ( core developer )
- Mail at yChat dot org ( reaches everybody of yChat )
+ Paul C. Buetow: Snooper at yhttpd point org ( core developer )
+ Volker Richter: Rover at yhttpd dot org ( core developer )
+ Mail at yhttpd dot org ( reaches everybody of yhttpd )
- ICQ
Paul C. Buetow: 11655527
@@ -449,8 +293,3 @@ You may contact us through the following addresses:
- IRC
#Ychat and #Coding at irc.german-elite.net
-//<<*
-1.9 YHTTPD CODE BASE GENERATION
-
-See docs/yhttpd.txt
-//*>>
diff --git a/bin/yhttpd b/bin/yhttpd
new file mode 100755
index 0000000..6c86c45
--- /dev/null
+++ b/bin/yhttpd
Binary files differ
diff --git a/configure b/configure
index 20e84d0..0f9f844 100755
--- a/configure
+++ b/configure
@@ -9,7 +9,7 @@ fi
perl -e '
use strict;
$|=1;
- sub check_gcc {
+ sub check {
my $f = shift;
my $s = shift;
my $r = 0;
@@ -29,32 +29,10 @@ perl -e '
print "GNU G++ $f.$s found!\n";
return $r;
}
- sub check_make {
- print "Checking for GNU make\n";
- my $err = "No GNU make found.\nPlease install a version of GNU make!\n";
- my $make;
- if (`which gmake`) {
- $make = "gmake";
- } elsif ( `which make` ) {
- $make = "make";
- } else {
- print $err;
- exit(1);
- }
-
- `sh -c "$make -v > make.version 2>/dev/null"`;
- if ( `cat make.version` =~ /GNU Make/ ) {
- `echo $make >> make.version`;
- } else {
- print $err;
- exit(1);
- }
- }
- &check_make;
print "Checking compiler version\n";
my $r = 0;
for (my $i = 4; $i > 0 && $r == 0; --$i ) {
- $r = &check_gcc(3,$i);
+ $r = &check(3,$i);
}
if ($r == 0) {
print "No suitable g++ compiler found!\n";
@@ -70,9 +48,4 @@ perl -e '
exit(0);
' `echo "$*" | sed "s/-//g"`
-if test -f err
-then
- rm -f err
-else
- echo You are ready to type gmake now!
-fi
+echo You are ready to type gmake now!
diff --git a/etc/yhttpd.conf b/etc/yhttpd.conf
new file mode 100644
index 0000000..e93bc32
--- /dev/null
+++ b/etc/yhttpd.conf
@@ -0,0 +1,620 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
+<category name="chat">
+ <option name="defaultop">
+ <value>Snoop</value>
+ <descr>The default user which has operator status</descr>
+ </option>
+ <option name="defaultrang">
+ <value>3</value>
+ <descr>The default user rang/status</descr>
+ </option>
+ <option name="defaultroom">
+ <value>Lounge</value>
+ <descr>The default chat room</descr>
+ </option>
+ <option name="printalwaystime">
+ <value>true</value>
+ <descr>If true, for each message in the chat window will be printed out the current time</descr>
+ </option>
+ <option name="timeoffset">
+ <value>0</value>
+ <descr>The time offset. Negative values are not allowed. If you have an offset of X please enter 24+X+12 here. Example: Offset = -6, 24-6+12 = 30 :)</descr>
+ </option>
+ <category name="permissions">
+ <option name="uptime">
+ <value>1</value>
+ </option>
+ <option name="ko">
+ <value>1</value>
+ </option>
+ <option name="topic">
+ <value>2</value>
+ </option>
+ <option name="ren">
+ <value>1</value>
+ </option>
+ <option name="version">
+ <value>3</value>
+ </option>
+ <option name="s">
+ <value>3</value>
+ </option>
+ <option name="msg">
+ <value>3</value>
+ </option>
+ <option name="me">
+ <value>3</value>
+ </option>
+ <option name="m">
+ <value>3</value>
+ </option>
+ <option name="j">
+ <value>3</value>
+ </option>
+ <option name="getroom">
+ <value>3</value>
+ </option>
+ <option name="away">
+ <value>3</value>
+ </option>
+ <option name="q">
+ <value>3</value>
+ </option>
+ <option name="time">
+ <value>3</value>
+ </option>
+ <option name="col">
+ <value>3</value>
+ </option>
+ <option name="help">
+ <value>3</value>
+ </option>
+ </category>
+ <category name="database">
+ <option name="mincon">
+ <value>9</value>
+ <descr>The amount of database connections which will be created at yhttpd startup</descr>
+ </option>
+ <option name="maxcon">
+ <value>10</value>
+ <descr>The maximum amount of concurrent connections to the database</descr>
+ </option>
+ <option name="contimeout">
+ <value>600</value>
+ <descr>Seconds of idling after a database connection will be closed. Will be checked once each minute</descr>
+ </option>
+ <option name="serverhost">
+ <value>fibonacci.exa-ds.com</value>
+ <descr>Specifies hostname oder ip address of the MySQL database server</descr>
+ </option>
+ <option name="user">
+ <value>yhttpd</value>
+ <descr>Specifies the MySQL username</descr>
+ </option>
+ <option name="password">
+ <value>yctest</value>
+ <descr>Specifies the MySQL password</descr>
+ </option>
+ <option name="dbname">
+ <value>yhttpd_advanced</value>
+ <descr>Specifies the MySQL database name</descr>
+ </option>
+ <option name="port">
+ <value>3306</value>
+ <descr>Specifies the MySQL server port</descr>
+ </option>
+ <category name="mysql">
+ <option name="registernick">
+ <value>user nick password color1 color2 email registerdate</value>
+ </option>
+ <option name="savechangednick">
+ <value>user password color1 color2 status email</value>
+ </option>
+ <option name="selectlogin">
+ <value>user nick password color1 color2 status email</value>
+ <descr>Specifies the fields which will be selected from the database if a registered user loggs in</descr>
+ </option>
+ <option name="selectnick">
+ <value>user nick</value>
+ <descr>Specifies the fields which will be selected from the database a user tries to logg in. Here only the nick will be fetched to check if the username is registered or not</descr>
+ </option>
+ </category>
+ </category>
+ <category name="maxlength">
+ <option name="message">
+ <value>500</value>
+ <descr>Maximum length of a chat message</descr>
+ </option>
+ <option name="username">
+ <value>15</value>
+ <descr>Maximum length of a user name</descr>
+ </option>
+ <option name="roomname">
+ <value>20</value>
+ <descr>Maximum length of a room name</descr>
+ </option>
+ <option name="emailaddress">
+ <value>20</value>
+ <descr>Maximum length of an email address</descr>
+ </option>
+ <option name="password">
+ <value>20</value>
+ <descr>Maximum length of the user password</descr>
+ </option>
+ <option name="topic">
+ <value>20</value>
+ <descr>Maximum length of a room&apos;s topic</descr>
+ </option>
+ </category>
+ <category name="system">
+ <option name="mysqlclient">
+ <value>/usr/local/bin/mysql</value>
+ <descr>Full path to the mysql client program</descr>
+ </option>
+ </category>
+ <category name="msgs">
+ <option name="servertime">
+ <value>The server system time:</value>
+ </option>
+ <option name="guest">
+ <value>This person is a guest chatter!</value>
+ </option>
+ <option name="lastactivity">
+ <value>Last activity:</value>
+ </option>
+ <option name="userrenamesroom">
+ <value> renames the room into </value>
+ </option>
+ <option name="optionschanged">
+ <value>Your options have been changed!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="rang0">
+ <value>Operator</value>
+ </option>
+ <option name="rang1">
+ <value>Half-Operator</value>
+ </option>
+ <option name="rang2">
+ <value>Voiced user</value>
+ </option>
+ <option name="registernick">
+ <value>Your nick has been registered successfully. You may log in now!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="reloadonlineframe">
+ <value>Reloaded online frame</value>
+ </option>
+ <option name="scream">
+ <value> screams:</value>
+ </option>
+ <option name="servertime">
+ <value>The server system time::</value>
+ </option>
+ <option name="setcommandstatus">
+ <value> sets command status</value>
+ </option>
+ <option name="setmodeaway">
+ <value> sets mode away:</value>
+ </option>
+ <option name="setmodefake">
+ <value>Fake modus acticated!</value>
+ </option>
+ <option name="setmodeinvisible">
+ <value>Invisible modus deactivated!</value>
+ </option>
+ <option name="topic">
+ <value> changes the topic to:</value>
+ </option>
+ <option name="topiccut">
+ <value>The topic you|ve choosen was too long and has been cut!</value>
+ </option>
+ <option name="topicdelete">
+ <value> deletes the topic of the room.</value>
+ </option>
+ <option name="unsetmodeaway">
+ <value> is back</value>
+ </option>
+ <option name="unsetmodefake">
+ <value>Fake modus deactivated!</value>
+ </option>
+ <option name="unsetmodeinvisible">
+ <value>Invisible modus deactivated!</value>
+ </option>
+ <option name="uptime">
+ <value>yhttpd uptime:</value>
+ </option>
+ <option name="userautoawaytimeout">
+ <value> has been set to away (auto away)</value>
+ </option>
+ <option name="userenterschat">
+ <value> enters the chat.</value>
+ </option>
+ <option name="userentersroom">
+ <value> enters the room </value>
+ </option>
+ <option name="userhasstatus">
+ <value> has status </value>
+ </option>
+ <option name="userinroom">
+ <value> is in room </value>
+ </option>
+ <option name="userkicksout1">
+ <value> kicks </value>
+ </option>
+ <option name="userkicksout2">
+ <value> out of the chat at room </value>
+ </option>
+ <option name="userleaveschat">
+ <value> leaves the chat.</value>
+ </option>
+ <option name="userleavesroom">
+ <value> leaves this room and switches to </value>
+ </option>
+ <option name="whisper">
+ <value> whispers to you</value>
+ </option>
+ <option name="whisperto">
+ <value>Whispered to </value>
+ </option>
+ <category name="help">
+ <option name="away">
+ <value>Sets mode away. Usage: /away AWAYTEST</value>
+ </option>
+ <option name="col">
+ <value>Changes the color. Usage: /col NICKCOLOR TEXTCOLOR</value>
+ </option>
+ <option name="exec">
+ <value>Executes a command in the system shell. Usage: /exec SHELLCOMMAND</value>
+ </option>
+ <option name="fake">
+ <value>Hides status logo. Usage: /fake</value>
+ </option>
+ <option name="getrusage">
+ <value>Shows informations describing the resources utilized by the yhttpd process. Usage: /getrusage</value>
+ </option>
+ <option name="help">
+ <value>Shows help text for a specific command. Usage: /help chatcommand</value>
+ </option>
+ <option name="invisible">
+ <value>Activates or deactivates the invisible mode</value>
+ </option>
+ <option name="j">
+ <value>Changes the room. Usage: /j ROOMNAME</value>
+ </option>
+ <option name="ko">
+ <value>Kicks a user out of the chat. Usage: /ko NICKNAME</value>
+ </option>
+ <option name="m">
+ <value>Writes the text italic (two colors). Usage: /m ACTION</value>
+ </option>
+ <option name="md5">
+ <value>MD5 hashes SOME STRINGS with SALT. Usage: /md5 SOME STRINGS SALT</value>
+ </option>
+ <option name="me">
+ <value>Writes the text italic (one color). Usage: /m ACTION</value>
+ </option>
+ <option name="msg">
+ <value>Whispers TEXT to NICKNAME. Usage: /msg NICKNAME TEXT</value>
+ </option>
+ <option name="version">
+ <value>Shows the version of the running yhttpd server. Usage: /version</value>
+ </option>
+ <option name="q">
+ <value>Leaving the chat. Usage: /q</value>
+ </option>
+ <option name="ren">
+ <value>Renames the current room into NEWROOMNAME. Usage: /ren NEWROOMNAME</value>
+ </option>
+ <option name="reload">
+ <value>Reloads the online frame of the current room. Usage: /reload</value>
+ </option>
+ <option name="set">
+ <value>Changes command permissions. P.e.: &quot;/set q status 3&quot; allows the command from status 3 or &quot;/set q disable 1&quot; deactivates the command. Disable 0 reactivates the command again. Usage: /set COMMAND MODE VAL</value>
+ </option>
+ <option name="getroom">
+ <value>Shows the room of the specific user. Useage: /getroom NICKNAME</value>
+ </option>
+ <option name="time">
+ <value>Shows the server system time. Usage: /time</value>
+ </option>
+ <option name="uptime">
+ <value>Shows the yhttpd uptime. Usage: /uptime</value>
+ </option>
+ <option name="s">
+ <value>Screams the TEXT. Usage: /s TEXT</value>
+ </option>
+ <option name="topic">
+ <value>Changes the topic of the current room into TOPIC. Usage: /topic TOPIC</value>
+ </option>
+ </category>
+ <category name="err">
+ <option name="alpnum">
+ <value>The nick you have specifued is not alphanumeric, please change that.&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="alreadyinroom">
+ <value>You are already in the room</value>
+ </option>
+ <option name="changepassword">
+ <value>The old password you have entered is wrong. In order to change your password you need to enter a correct old password!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="changepassword2">
+ <value>The two password fiels oth the new password are not identical. Please check that again otherwise the password will not be changed!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="emaillength">
+ <value>Your email address is too long!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="execcommand">
+ <value>Could not execute command!</value>
+ </option>
+ <option name="findingcommand">
+ <value>No such command!&lt;br&gt;</value>
+ </option>
+ <option name="messagelength">
+ <value>Your message was too long and has been shortened!</value>
+ </option>
+ <option name="nicklength">
+ <value>Your nick is too long!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="nonick">
+ <value>You need to specify a nickname!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="noroom">
+ <value>You have to enter a valid room name!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="notavailable">
+ <value>is not available!</value>
+ </option>
+ <option name="notonline">
+ <value>An error occured. Your nick is not online!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="online">
+ <value>The nick you have specified is already online. Please try another nick!!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="passlength">
+ <value>Your password is too long!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="registerexists">
+ <value>The nickname you want to register already exists. Please choose another one!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="registerpassword">
+ <value>The password selections differ. Please re-enter your password fields!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="roomexists">
+ <value>The new name of the room you have choosen is already taken by another room!</value>
+ </option>
+ <option name="roomnamelength">
+ <value>Your room name too long!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ <option name="wrongcommandusage">
+ <value>Wrong command usage. Please read the help site!</value>
+ </option>
+ <option name="wrongpassword">
+ <value>The nickname you have selected already exists in the user database and you have entered a wrong password!&lt;br&gt;&lt;br&gt;</value>
+ </option>
+ </category>
+ </category>
+ <category name="idle">
+ <option name="awaytimeout">
+ <value>1800</value>
+ <descr>Seconds of inanctivity after a user will get logged out if the user is away</descr>
+ </option>
+ <option name="autoawaytimeout">
+ <value>500</value>
+ <descr>Seconds until a user will be set to away automatically</descr>
+ </option>
+ <option name="timeout">
+ <value>900</value>
+ <descr>Seconds of inactivity after a user will get logged out automatically</descr>
+ </option>
+ </category>
+ <category name="session">
+ <option name="md5hash">
+ <value>true</value>
+ <descr>If set to true, then the session id will be hashed by MD5 to make the id even more random</descr>
+ </option>
+ <option name="md5salt">
+ <value>tASDlkjadSD</value>
+ </option>
+ <option name="length">
+ <value>64</value>
+ <descr>Length of the generated session id. The length will be shorter if md5hash is activated</descr>
+ </option>
+ <option name="validchars">
+ <value>.abcdefghijklmnopqrstuvwxyz0123456789-_</value>
+ <descr>Valid chars which can be in a session id. The generated session will use other chars if md5hash is activated</descr>
+ </option>
+ <option name="kloakkey">
+ <value>123987</value>
+ <descr>Some numner which will affect the session id. Change this to another random number!</descr>
+ </option>
+ </category>
+ <category name="html">
+ <option name="tagsallow">
+ <value>false</value>
+ <descr>If set to false, yhttpd strips all html tags from incoming messages</descr>
+ </option>
+ <option name="errorcolor">
+ <value>FF0000</value>
+ <descr>Specifies the standard error message color</descr>
+ </option>
+ <option name="onlinebefore">
+ <value>&lt;tr&gt;&lt;td&gt;</value>
+ <descr>HTML-Tags which will be placed before each nickname in the user online frame</descr>
+ </option>
+ <option name="onlinebehind">
+ <value>&lt;/td&gt;&lt;/tr&gt;</value>
+ <descr>HTML-Tags which will be placed behind each nickname in the user online frame</descr>
+ </option>
+ <category name="rangimages">
+ <option name="location">
+ <value>images/</value>
+ <descr>Specifies the location of the status (status) symbols of the users. This path has to be reachable through the web, e.g.: &quot;http://www.webreachable.com/images/&quot;. If no http:// is specified then the images are inside the conf:httpd.templatedir directory</descr>
+ </option>
+ <option name="options">
+ <value> width=&quot;16&quot; height=&quot;16&quot;</value>
+ <descr>Options to add to the &lt;img&gt; tag (leave first char blank)</descr>
+ </option>
+ </category>
+ <category name="user">
+ <option name="color1">
+ <value>AAAAAA</value>
+ <descr>User&apos;s standard nick color in hexadecimal</descr>
+ </option>
+ <option name="color2">
+ <value>FFFFFF</value>
+ <descr>User&apos;s standard text color in hexadecimal</descr>
+ </option>
+ </category>
+ <category name="replace">
+ <option name="activate">
+ <value>true</value>
+ <descr>If set to true, then this replace option will be used</descr>
+ </option>
+ <category name="from">
+ <option name="red">
+ <value>red</value>
+ </option>
+ <option name="green">
+ <value>green</value>
+ </option>
+ <option name="orange">
+ <value>orange</value>
+ </option>
+ <option name="yellow">
+ <value>yellow</value>
+ </option>
+ </category>
+ <category name="into">
+ <option name="red">
+ <value>&lt;font color=&quot;red&quot;&gt;red&lt;/font&gt;</value>
+ </option>
+ <option name="green">
+ <value>&lt;font color=&quot;green&quot;&gt;green&lt;/font&gt;</value>
+ </option>
+ <option name="orange">
+ <value>&lt;font color=&quot;orange&quot;&gt;orange&lt;/font&gt;</value>
+ </option>
+ <option name="yellow">
+ <value>&lt;font color=&quot;yellow&quot;&gt;yellow&lt;/font&gt;</value>
+ </option>
+ </category>
+ </category>
+ </category>
+ <category name="logging">
+ <option name="roomlogdir">
+ <value>log/rooms/</value>
+ <descr>Specifies the relative or absolute path to the directory of the room log files</descr>
+ </option>
+ <option name="roomloglines">
+ <value>10</value>
+ <descr>Number of room log lines which will be buffered in the main memory until they will be written into the file</descr>
+ </option>
+ </category>
+</category>
+<category name="httpd">
+ <option name="serverport">
+ <value>2000</value>
+ <descr>Local port on which the server listens</descr>
+ </option>
+ <option name="enablecgi">
+ <value>false</value>
+ <descr>Support for CGI scripts</descr>
+ </option>
+ <option name="startsite">
+ <value>index.html</value>
+ <descr>Specifies the standard start HTML-template</descr>
+ </option>
+ <option name="templatedir">
+ <value>html/</value>
+ <descr>If set to false, yhttpd strips all html tags from incoming messages</descr>
+ </option>
+ <category name="html">
+ <option name="notfound">
+ <value>notfound.html</value>
+ <descr>The HTML site which will be displayed if the requested file does not exists</descr>
+ </option>
+ </category>
+ <category name="thread">
+ <option name="poolsize">
+ <value>50</value>
+ <descr>Number of threads running at the same time</descr>
+ </option>
+ <option name="queuesize">
+ <value>10</value>
+ <descr>Max. number of jobs which can wait for a free thread of the thread pool</descr>
+ </option>
+ </category>
+ <category name="stats">
+ <option name="rusagehistory">
+ <value>7</value>
+ <descr>Number of days to track the system resource usage. You can check the history in the CLI mode</descr>
+ </option>
+ </category>
+ <category name="system">
+ <option name="shell">
+ <value>tcsh</value>
+ <descr>The external command for the system shell which can be selected in the CLI mode</descr>
+ </option>
+ </category>
+ <category name="modules">
+ <option name="commandsdir">
+ <value>mods/commands/</value>
+ <descr>Specifies the relative or absolute path to the command&apos;s .so module files which can be loaded and unloaded at runtime</descr>
+ </option>
+ <option name="htmldir">
+ <value>mods/html/</value>
+ <descr>Specifies the relative or absolute path to the html&apos;s .so module files which can be loaded and unloaded at runtime</descr>
+ </option>
+ <option name="preloadcommands">
+ <value>true</value>
+ <descr>If set to true, all command modules will be preloaded at server startup</descr>
+ </option>
+ <option name="preloadhtml">
+ <value>false</value>
+ <descr>If set to true, all html modules will be preloaded at server startup</descr>
+ </option>
+ </category>
+ <category name="logging">
+ <option name="accessfile">
+ <value>log/access_log</value>
+ <descr>Specifies the relative or absolute path to the apache combined style log file</descr>
+ </option>
+ <option name="systemfile">
+ <value>log/system_log</value>
+ <descr>Specifies the relative or absolute path to the system messsage log file</descr>
+ </option>
+ <option name="accesslines">
+ <value>10</value>
+ <descr>Number of access log lines which will be buffered in the main memory until they will be written into the file</descr>
+ </option>
+ <option name="systemlines">
+ <value>10</value>
+ <descr>Number of system log lines which will be buffered in the main memory until they will be written into the file</descr>
+ </option>
+ </category>
+ <category name="contenttypes">
+ <option name="htm">
+ <value>text/html</value>
+ </option>
+ <option name="html">
+ <value>text/html</value>
+ </option>
+ <option name="gif">
+ <value>image/gif</value>
+ </option>
+ <option name="jpg">
+ <value>image/jpeg</value>
+ </option>
+ <option name="jpe">
+ <value>image/jpeg</value>
+ </option>
+ <option name="jpeg">
+ <value>image/jpeg</value>
+ </option>
+ <option name="png">
+ <value>image/png</value>
+ </option>
+ <option name="default">
+ <value>text/html</value>
+ </option>
+ </category>
+</category>
diff --git a/html/index.html b/html/index.html
index 983e7ef..b1a1793 100755
--- a/html/index.html
+++ b/html/index.html
@@ -3,52 +3,25 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>
- %%ychat.version%%
+ %%yhttpd.version%%
</title>
<link rel=stylesheet href="style.css" type=text/css>
</head>
-<body>
+<body bgcolor=#000000 text=#ffff00>
<table align=center width=500>
<tr>
-<td>
-<center>
-%%ychat.version%%<br><br>%%INFO%%
-</center>
-</td>
+<td align=center class=header>%%yhttpd.version%%<br><br>%%INFO%%</td>
</tr>
<tr>
<td colspan=2>&nbsp;</td>
</tr>
<tr>
<td align=center colspan=2>
-<form action="frameset.html" method="POST">
- <input type="hidden" name="event" value="login">
-Enter your nick:<br>
- <input class="text" type="text" name="nick" value="%%nick%%" maxlength="%%chat.maxlength.username%%" accesskey="n">
-<br>
-<br>
-Enter your password:<br>
- <input class="text" type="password" name="password" value="%%pass%%" maxlength="%%chat.maxlength.password%%" accesskey="p">
-<br>
-<br>
-Enter your room:<br>
- <input class="text" type="text" name="room" value="%%chat.defaultroom%%" maxlength="%%chat.maxlength.roomname%%" accesskey="r">
-<br>
-<br>
- <input type="hidden" name="end" value="end">
- <input type="submit" value="login" accesskey="s">
-</form>
-<br>
-<a class="fancy" href="register.html">Register</a> a new nick
-<br>
-<br>
-If you don't want to register you may login
-<br>
-without a password using an unregistered nick.
+This is the demo website provided by yhttpd :-)
</td>
</tr>
</table>
<br><br>
-<center><span class="signature">yChat is OpenSource - get it at <a class="fancy" target="_blank" href="http://www.yChat.org">http://www.yChat.org</a></span></center>
+<center><span class="signature">yhttpd is OpenSource - get it at <a target="_blank" href="http://www.yhttpd.org">http://www.yhttpd.org</a></span></center>
</body>
</html>
diff --git a/html/style.css b/html/style.css
index 4b6d9ca..e31bd7e 100755
--- a/html/style.css
+++ b/html/style.css
@@ -1,48 +1,11 @@
-body, div {
+BODY, TD {
font-family: Verdana, Helvetica, sans-serif;
- background-color: #000000;
- color: #FFFFEF;
font-size: 11pt;
}
-
-input {
- color: #000000;
- font-family: Verdana, Helvetica, sans-serif;
- text-decoration: none;
- font-size: 9pt;
- padding: 2px;
-}
-
-input.text {
- background-color: #FFFFEF;
-}
-
-.fancy {
- font-family: Verdana, Helvetica, sans-serif;
- font-size: 9pt;
- color: #FFFFEF;
- padding: 2px;
-}
-
-a:hover.fancy {
- text-decoration: none;
- color: #FFFFEF;
- background-color: #000000;
-}
-
-h1 {
- background-color: #ffa500;
- border: solid #000000 1px;
- font-size: 20pt;
- padding: 13px;
- font-width: bold;
-}
-
-body.stream {
- background-color: #323232;
+A {
+ color: #dddddd;
}
-
.signature {
- color: #AAAAAA;
+ color: #dddddd;
font-size: 9pt;
}
diff --git a/scripts/README b/scripts/README
index 189b169..4a94391 100644
--- a/scripts/README
+++ b/scripts/README
@@ -1,4 +1,4 @@
-All scripts should be run from the yChat main directory, example:
+All scripts should be run from the yhttpd main directory, example:
./scripts/makeyhttpd.pl
diff --git a/scripts/buildnr.pl b/scripts/buildnr.pl
index ee3d3e2..4698f8d 100755
--- a/scripts/buildnr.pl
+++ b/scripts/buildnr.pl
@@ -1,8 +1,8 @@
#!/usr/bin/perl
-# The yChat Project (2003)
+# The yhttpd Project (2003)
#
-# This script increases the BUILNR of msgs,h each time the yChat
+# This script increases the BUILNR of msgs,h each time the yhttpd
# gets recompiled!
use strict;
@@ -13,7 +13,7 @@ close MSGS;
foreach (@msgs)
{
- if ( /define BUILDNR/ )
+ if ( /BUILDNR/ )
{
s/(BUILDNR )(.+)$/$1.($2+1)/e;
print;
diff --git a/scripts/config.sh b/scripts/config.sh
index 373fad4..f301246 100755
--- a/scripts/config.sh
+++ b/scripts/config.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# The yChat Project (2004)
+# The yhttpd Project (2004)
#
# This script modifues the src/glob.h file.
@@ -15,11 +15,11 @@ perl -e '
use scripts::modules::file;
print <<END;
-Welcome to the yChat configurator!
+Welcome to the yhttpd configurator!
You may also edit the src/glob.h file manually instead of using
this configurator option. Please also notice that this are only
before-compile options. All setups which can be made after com-
-iling are placed in the yChat configuration file.
+iling are placed in the yhttpd configuration file.
END
my $sep = "================================================================\n"; my $stdin;
diff --git a/scripts/screen.sh b/scripts/screen.sh
index 6d5b7aa..5c227fc 100755
--- a/scripts/screen.sh
+++ b/scripts/screen.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-screen -S ychat ./bin/ychat
+screen -S yhttpd ./bin/yhttpd
diff --git a/scripts/setglobvals.pl b/scripts/setglobvals.pl
index 13288a5..1ee1de4 100755
--- a/scripts/setglobvals.pl
+++ b/scripts/setglobvals.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# The yChat Project (2003)
+# The yhttpd Project (2003)
#
# This script sets up some variables in src/glob.h
diff --git a/scripts/stats.pl b/scripts/stats.pl
index e5cc2b3..fcbcd33 100755
--- a/scripts/stats.pl
+++ b/scripts/stats.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# The yChat Project (2003 - 2004)
+# The yhttpd Project (2003 - 2004)
#
# This script generates source code and project statistics
@@ -9,7 +9,6 @@ use strict;
use scripts::modules::file;
my %stats;
-my $param = shift;
&recursive(".");
@@ -18,16 +17,19 @@ $stats{"Lines total"} = $stats{"Lines of source"}
+ $stats{"Lines of text"}
+ $stats{"Lines of HTML"};
-unless (defined $param) {
-
- print "$_ = " . $stats{$_} . "\n"
- for ( sort keys %stats );
-
-} else {
-
- print $stats{$_} . " "
- for sort keys %stats;
-
+my $bool = 0;
+foreach ( sort keys %stats )
+{
+ if ($bool == 0)
+ {
+ print "$_ = " . $stats{$_} . "\n";
+ $bool = 1;
+ }
+ else
+ {
+ print "$_ = " . $stats{$_} . "\n";
+ $bool = 0;
+ }
}
print "\n";
diff --git a/src/Makefile.in b/src/Makefile.in
index 0382389..262f3a6 100755
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -6,16 +6,16 @@ LDFLAGS=$(LIBADD) -lstdc++
LDADD=-pthread -D_THREAD_SAFE -export-dynamic -ldl
INCLUDES=`cat includes.add`
CFLAGS=-fno-inline -fno-default-inline -frepo
-all: ychat
+all: yhttpd
$(SRCS):
$(CC) $(INCLUDES) $(CFLAGS) -c $*.cpp
infotext:
@echo Compiling base
-ychat: infotext $(OBJS)
+yhttpd: infotext $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDADD)
- @mv ychat ../bin
+ @mv yhttpd ../bin
@echo -n "Size of linked executable: "
- @du -hc ../bin/ychat | tail -n 1
+ @du -hc ../bin/yhttpd | tail -n 1
clean:
@echo Cleaning base obj
@if test -d ../obj; then rm -Rf ../obj; fi
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index 2956264..f35f77c 100755
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -9,296 +9,255 @@ using namespace std;
cli::cli( )
{
#ifdef NCURSES
- start();
+ start();
#endif
}
cli::~cli()
-{}
-
+{
+}
int
cli::parse_input( string s_input )
{
- string s_param = "";
- unsigned i_pos = s_input.find_first_of(" ");
-
- if ( i_pos != string::npos )
- {
- s_param = s_input.substr(i_pos+1);
- s_input = s_input.substr(0, i_pos);
- }
-
- if ( s_input.compare("help") == 0 || s_input.compare("h") == 0)
- {
- cout << CLIPRMO << "COMMAND LINE INTERFACE HELP MENU" << endl;
- cout << CLIPRMO << " !command - Uses system to run a command" << endl;
+ string s_param = "";
+ unsigned i_pos = s_input.find_first_of(" ");
+ if ( i_pos != string::npos ) {
+ s_param = s_input.substr(i_pos+1);
+ s_input = s_input.substr(0, i_pos);
+ }
+
+ if ( s_input.compare("help") == 0 || s_input.compare("h") == 0)
+ {
+ cout << CLIPRMO << "COMMAND LINE INTERFACE HELP MENU" << endl;
#ifdef DEBUG
-
- cout << CLIPRMO << " (d)ebug - Starts debug routine (cli.cpp)" << endl;
+ cout << CLIPRMO << " (d)ebug - Starts debug routine (cli.cpp)" << endl;
#endif
-
- cout << CLIPRMO << " (e)cho VAR - Prints out configuration value of VAR" << endl
- << CLIPRMO << " Wildcards can be used too, example: echo http*" << endl;
+ cout << CLIPRMO << " (e)cho VAR - Prints out configuration value of VAR" << endl
+ << CLIPRMO << " Wildcards can be used too, example: echo HTML*" << endl
+ << CLIPRMO << " (h)elp - Prints out this help!" << endl
+ << CLIPRMO << " (m)ysql - Runs MySQL client on yhttpd DB" << endl;
#ifdef NCURSES
-
- cout << CLIPRMO << " (ex)it - Quits CLI mode and respawns ncurses mode" << endl;
+ cout << CLIPRMO << " (q)uit - Quits CLI mode and respawns ncurses mode" << endl;
#endif
-
- cout << CLIPRMO << " (h)elp - Prints out this help!" << endl;
- //<<*
- cout << CLIPRMO << " (m)ysql - Runs MySQL client on yChat DB" << endl
- << CLIPRMO << " (rel)oad - Reloads all modules" << endl;
- //*>>
+ cout << CLIPRMO << " (rel)oad - Reloads all modules" << endl;
#ifdef EXPERIM
-
- cout << CLIPRMO << " (re)conf - Reloads configuration (EXPERIMENTAL)" << endl;
+ cout << CLIPRMO << " (re)conf - Reloads configuration (EXPERIMENTAL)" << endl;
#endif
+ cout << CLIPRMO << " (r)usage - Shows current resource usage" << endl
+ << CLIPRMO << " (ru)sageh - Shows resource usage history (yhttpd needs to run > 1 day)" << endl
+ << CLIPRMO << " (set) VAR VAL - Sets configuration value VAR to VAL" << endl
+ << CLIPRMO << " (sh)ell - Runs a system shell" << endl
+ << CLIPRMO << " (s)hutdown - Shuts down the whole server" << endl
+ << CLIPRMO << " (t)ime - Prints out time and uptime" << endl
+ << CLIPRMO << " (unl)oad - Unloads all loaded modules" << endl
+ << CLIPRMO << " (u)nset VAR - Deltetes configuration value VAR" << endl
+ << CLIPRMO << " (v)ersion - Prints out version" << endl;
+ cout << CLIPRMI;
+ }
- cout << CLIPRMO << " (r)usage - Shows current resource usage" << endl
- << CLIPRMO << " (ru)sageh - Shows resource usage history (yChat needs to run > 1 day)" << endl
- << CLIPRMO << " (set) VAR VAL - Sets configuration value VAR to VAL" << endl
- << CLIPRMO << " (sh)ell - Runs a system shell" << endl
- << CLIPRMO << " (s)hutdown - Shuts down the whole server" << endl
- << CLIPRMO << " (t)ime - Prints out time and uptime" << endl;
- cout << CLIPRMO << " (unl)oad - Unloads all loaded modules" << endl;//<<
- cout << CLIPRMO << " (u)nset VAR - Deletes configuration value VAR" << endl
- << CLIPRMO << " (v)ersion - Prints out version" << endl;
- cout << CLIPRMI;
- }
- else if( s_input.at(0) == '!' )
- {
- system( s_input.substr(1).c_str() );
- cout << CLIPRMI;
- }
#ifdef DEBUG
- else if( s_input.compare("d") == 0 || s_input.compare("debug") == 0 )
- {
- debug_routine();
- cout << CLIPRMI;
- }
+ else if( s_input.compare("d") == 0 || s_input.compare("debug") == 0 )
+ {
+ debug_routine();
+ cout << CLIPRMI;
+ }
#endif
- else if( s_input.compare("echo") == 0 || s_input.compare("e") == 0 )
- {
- string s_val;
-
- // Check wildcards
- unsigned i_pos = s_param.find("*");
- if ( i_pos != string::npos )
- {
- s_param = s_param.substr( 0, i_pos );
- vector<string>* p_vec = wrap::CONF->get_key_vector();
- sort(p_vec->begin(), p_vec->end());
- vector<string>::iterator iter;
-
- for ( iter = p_vec->begin(); iter != p_vec->end(); iter++ )
- if ( iter->find(s_param) == 0 )
- s_val.append( *iter + " := " + wrap::CONF->get_elem(*iter) + "\n" + CLIPRMO );
- delete p_vec;
- }
- else
- {
- s_val = wrap::CONF->get_elem(s_param);
- }
-
- if( s_val.empty() )
- s_val = "Value not set";
-
- cout << CLIPRMO << s_val << endl;
- cout << CLIPRMI;
- }
-
- //<<*
- else if( s_input.compare("mysql") == 0 || s_input.compare("m") == 0 )
- {
- cout << CLIPRMO << CLIMSQL << endl;
-
- system((wrap::CONF->get_elem("chat.system.mysqlclient") + " -p -h " +
- wrap::CONF->get_elem("chat.database.serverhost") + " -u " +
- wrap::CONF->get_elem("chat.database.user") ).c_str());
-
- cout << CLIPRMO << CLIWELC << endl;
- cout << CLIPRMI;
- }
- //*>>
-
+ else if( s_input.compare("echo") == 0 || s_input.compare("e") == 0 )
+ {
+ string s_val;
+ // Check wildcards
+ unsigned i_pos = s_param.find("*");
+ if ( i_pos != string::npos )
+ {
+ s_param = s_param.substr( 0, i_pos );
+ vector<string>* p_vec = wrap::CONF->get_key_vector();
+ sort(p_vec->begin(), p_vec->end());
+ vector<string>::iterator iter;
+ for ( iter = p_vec->begin(); iter != p_vec->end(); iter++ )
+ if ( iter->find(s_param) == 0 )
+ s_val.append( *iter + " := " + wrap::CONF->get_elem(*iter) + "\n" + CLIPRMO );
+ delete p_vec;
+ }
+ else
+ {
+ s_val = wrap::CONF->get_elem(s_param);
+ }
+
+ if( s_val.empty() )
+ s_val = "Value not set";
+ cout << CLIPRMO << s_val << endl;
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("mysql") == 0 || s_input.compare("m") == 0 )
+ {
+ cout << CLIPRMO << CLIMSQL << endl;
+ system((wrap::CONF->get_elem("chat.system.mysqlclient") + " -p -h " +
+ wrap::CONF->get_elem("chat.database.serverhost") + " -u " +
+ wrap::CONF->get_elem("chat.database.user") ).c_str());
+ cout << CLIPRMO << CLIWELC << endl;
+ cout << CLIPRMI;
+ }
#ifdef NCURSES
- else if( s_input.compare("exit") == 0 || s_input.compare("ex") == 0 )
- {
- return 0;
- }
+ else if( s_input.compare("quit") == 0 || s_input.compare("q") == 0 )
+ {
+ return 0;
+ }
#endif
-
- //<<*
- else if( s_input.compare("reload") == 0 || s_input.compare("rel") == 0 )
- {
- cout << CLIPRMO;
- wrap::MODL->reload_modules();
- cout << CLIPRMI;
- }
- //*>>
-
+ else if( s_input.compare("reload") == 0 || s_input.compare("rel") == 0 )
+ {
+ cout << CLIPRMO;
+ wrap::MODL->reload_modules();
+ cout << CLIPRMI;
+ }
#ifdef EXPERIM
- else if( s_input.compare("reconf") == 0 || s_input.compare("re") == 0 )
- {
- wrap::CHAT->reconf();
- cout << CLIPRMI;
- }
+ else if( s_input.compare("reconf") == 0 || s_input.compare("re") == 0 )
+ {
+ wrap::HTTPD->reconf();
+ cout << CLIPRMI;
+ }
#endif
-
- else if( s_input.compare("rusage") == 0 || s_input.compare("r") == 0 )
- {
- print_rusage();
- cout << CLIPRMI;
- }
- else if( s_input.compare("ru") == 0 || s_input.compare("rusageh") == 0 )
- {
- cout << wrap::STAT->get_rusage_history( "ru_maxrss", string(CLIPRMO) + " " );
- cout << CLIPRMI;
- }
- else if( s_input.compare("set") == 0 )
- {
- string s_varname = "";
- i_pos = s_param.find_first_of(" ");
-
- if ( i_pos != string::npos )
- {
- s_varname = s_param.substr(0, i_pos);
-
- if ( s_param.length() > i_pos+1 )
- s_param = s_param.substr(i_pos+1);
-
- else
- s_param = "";
- }
-
- string s_old_val = wrap::CONF->get_elem(s_varname);
-
- if ( !s_old_val.empty() )
- {
- cout << CLIPRMO << "Old value: " << s_old_val << endl;
- wrap::CONF->del_elem(s_varname);
- }
-
- wrap::CONF->add_elem(s_param, s_varname);
- cout << CLIPRMO << "New value: " << s_param << endl;
- cout << CLIPRMI;
- }
- else if( s_input.compare("shell") == 0 || s_input.compare("sh") == 0 )
- {
- cout << CLIPRMO << CLISHEL << endl;
- system(wrap::CONF->get_elem("httpd.system.shell").c_str());
- cout << CLIPRMO << CLIWELC << endl;
- cout << CLIPRMI;
- }
- else if( s_input.compare("shutdown") == 0 || s_input.compare("s") == 0 )
- {
- exit(0);
- }
- else if( s_input.compare("t") == 0 || s_input.compare("time") == 0 )
- {
- cout << CLIPRMO << "Time: " << wrap::TIMR->get_time() << endl
- << CLIPRMO << "Uptime: " << wrap::TIMR->get_uptime() << endl;
- cout << CLIPRMI;
- }
-
- //<<*
- else if( s_input.compare("unl") == 0 || s_input.compare("unload") == 0 )
- {
- cout << CLIPRMO;
- wrap::MODL->unload_modules();
- cout << CLIPRMI;
+ else if( s_input.compare("rusage") == 0 || s_input.compare("r") == 0 )
+ {
+ print_rusage();
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("ru") == 0 || s_input.compare("rusageh") == 0 )
+ {
+ cout << wrap::STAT->get_rusage_history( "ru_maxrss", string(CLIPRMO) + " " );
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("set") == 0 )
+ {
+ string s_varname = "";
+ i_pos = s_param.find_first_of(" ");
+ if ( i_pos != string::npos ) {
+ s_varname = s_param.substr(0, i_pos);
+ if ( s_param.length() > i_pos+1 )
+ s_param = s_param.substr(i_pos+1);
+ else
+ s_param = "";
}
- //*>>
- else if( s_input.compare("u") == 0 || s_input.compare("unset") == 0 )
- {
- if (!s_param.empty())
- {
- string s_old_val = wrap::CONF->get_elem(s_param);
- if ( !s_old_val.empty() )
- {
- cout << CLIPRMO << "Deleted variable " << s_param << " with value: " << s_old_val << endl;
- wrap::CONF->del_elem(s_param);
- }
- else
- {
- cout << CLIPRMO << "Variable " << s_param << " was not set" << endl;
- }
- cout << CLIPRMI;
- }
- }
- else if( s_input.compare("v") == 0 || s_input.compare("version") == 0 )
+ string s_old_val = wrap::CONF->get_elem(s_varname);
+ if ( !s_old_val.empty() )
{
- cout << CLIPRMO << tool::ychat_version() << " " << UNAME << endl;
- cout << CLIPRMI;
+ cout << CLIPRMO << "Old value: " << s_old_val << endl;
+ wrap::CONF->del_elem(s_varname);
}
- else
+ wrap::CONF->add_elem(s_param, s_varname);
+ cout << CLIPRMO << "New value: " << s_param << endl;
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("shell") == 0 || s_input.compare("sh") == 0 )
+ {
+ cout << CLIPRMO << CLISHEL << endl;
+ system(wrap::CONF->get_elem("httpd.system.shell").c_str());
+ cout << CLIPRMO << CLIWELC << endl;
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("shutdown") == 0 || s_input.compare("s") == 0 )
+ {
+ exit(0);
+ }
+ else if( s_input.compare("t") == 0 || s_input.compare("time") == 0 ) {
+ cout << CLIPRMO << "Time: " << wrap::TIMR->get_time() << endl
+ << CLIPRMO << "Uptime: " << wrap::TIMR->get_uptime() << endl;
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("unl") == 0 || s_input.compare("unload") == 0 ) {
+ cout << CLIPRMO;
+ wrap::MODL->unload_modules();
+ cout << CLIPRMI;
+ }
+ else if( s_input.compare("u") == 0 || s_input.compare("unset") == 0 )
+ {
+ if (!s_param.empty())
{
- cout << CLIPRMO << CLIHELP << "\"" << s_input << "\"" << endl;
- cout << CLIPRMI;
+ string s_old_val = wrap::CONF->get_elem(s_param);
+ if ( !s_old_val.empty() )
+ {
+ cout << CLIPRMO << "Deleted variable " << s_param << " with value: " << s_old_val << endl;
+ wrap::CONF->del_elem(s_param);
+ }
+ else
+ {
+ cout << CLIPRMO << "Variable " << s_param << " was not set" << endl;
+ }
+ cout << CLIPRMI;
}
+ }
+ else if( s_input.compare("v") == 0 || s_input.compare("version") == 0 )
+ {
+ cout << CLIPRMO << tool::yhttpd_version() << " " << UNAME << endl;
+ cout << CLIPRMI;
+ }
+ else
+ {
+ cout << CLIPRMO << CLIHELP << "\"" << s_input << "\"" << endl;
+ cout << CLIPRMI;
+ }
- return 1;
+ return 1;
}
void
#ifndef NCURSES
cli::start(void* p_void)
#else
-cli::start()
+cli::start()
#endif
{
- cout << CLIPRMO << CLIWELC << endl;
+ cout << CLIPRMO << CLIWELC << endl;
- string s_input;
- cout << CLIPRMI;
+ string s_input;
+ cout << CLIPRMI;
- do
- {
- getline(cin, s_input);
- }
- while( parse_input(s_input) );
+ do
+ {
+ getline(cin, s_input);
+ }
+ while( parse_input(s_input) );
}
void
cli::print_rusage()
{
- rusage* p_rusage = new rusage;
- getrusage( RUSAGE_SELF, p_rusage );
-
- cout << CLIPRMO << "ru_maxrss: " << p_rusage->ru_maxrss << "\t(max resident set size)" << endl
- << CLIPRMO << "ru_ixrss: " << p_rusage->ru_ixrss << "\t(integral shared text memory size)" << endl
- << CLIPRMO << "ru_idrss: " << p_rusage->ru_idrss << "\t(integral unshared data size)" << endl
- << CLIPRMO << "ru_isrss: " << p_rusage->ru_isrss << "\t(integral unshared stack size)" << endl
- << CLIPRMO << "ru_minflt: " << p_rusage->ru_minflt << "\t(page reclaims)" << endl
- << CLIPRMO << "ru_majflt: " << p_rusage->ru_majflt << "\t(page faults)" << endl
- << CLIPRMO << "ru_nswap: " << p_rusage->ru_nswap << "\t(swaps)" << endl
- << CLIPRMO << "ru_inblock: " << p_rusage->ru_inblock << "\t(block input operations)" << endl
- << CLIPRMO << "ru_oublock: " << p_rusage->ru_oublock << "\t(block output operations)" << endl
- << CLIPRMO << "ru_msgsnd: " << p_rusage->ru_msgsnd << "\t(messages sent)" << endl
- << CLIPRMO << "ru_msgrcv: " << p_rusage->ru_msgrcv << "\t(messages received)" << endl
- << CLIPRMO << "ru_nsignals: " << p_rusage->ru_nsignals << "\t(signals received)" << endl
- << CLIPRMO << "ru_nvcsw: " << p_rusage->ru_nvcsw << "\t(voluntary context switches)" << endl
- << CLIPRMO << "ru_nivcsw: " << p_rusage->ru_nivcsw << "\t(involuntary context switches)" << endl;
-
- delete p_rusage;
+ rusage* p_rusage = new rusage;
+ getrusage( RUSAGE_SELF, p_rusage );
+
+ cout << CLIPRMO << "ru_maxrss: " << p_rusage->ru_maxrss << "\t(max resident set size)" << endl
+ << CLIPRMO << "ru_ixrss: " << p_rusage->ru_ixrss << "\t(integral shared text memory size)" << endl
+ << CLIPRMO << "ru_idrss: " << p_rusage->ru_idrss << "\t(integral unshared data size)" << endl
+ << CLIPRMO << "ru_isrss: " << p_rusage->ru_isrss << "\t(integral unshared stack size)" << endl
+ << CLIPRMO << "ru_minflt: " << p_rusage->ru_minflt << "\t(page reclaims)" << endl
+ << CLIPRMO << "ru_majflt: " << p_rusage->ru_majflt << "\t(page faults)" << endl
+ << CLIPRMO << "ru_nswap: " << p_rusage->ru_nswap << "\t(swaps)" << endl
+ << CLIPRMO << "ru_inblock: " << p_rusage->ru_inblock << "\t(block input operations)" << endl
+ << CLIPRMO << "ru_oublock: " << p_rusage->ru_oublock << "\t(block output operations)" << endl
+ << CLIPRMO << "ru_msgsnd: " << p_rusage->ru_msgsnd << "\t(messages sent)" << endl
+ << CLIPRMO << "ru_msgrcv: " << p_rusage->ru_msgrcv << "\t(messages received)" << endl
+ << CLIPRMO << "ru_nsignals: " << p_rusage->ru_nsignals << "\t(signals received)" << endl
+ << CLIPRMO << "ru_nvcsw: " << p_rusage->ru_nvcsw << "\t(voluntary context switches)" << endl
+ << CLIPRMO << "ru_nivcsw: " << p_rusage->ru_nivcsw << "\t(involuntary context switches)" << endl;
+
+ delete p_rusage;
}
#ifdef DEBUG
void
cli::debug_routine()
{
- rusage* p_rusage = new rusage;
- for(;;)
- {
- /*
- ossl *p_tmp = new ossl;
- getrusage( RUSAGE_SELF, p_rusage );
- cout << CLIPRMO << "ru_maxrss: " << p_rusage->ru_maxrss << "\t(max resident set size)" << endl;
- delete p_tmp;
- */
- }
- delete p_rusage;
+ rusage* p_rusage = new rusage;
+ for(;;)
+ {
+/*
+ ossl *p_tmp = new ossl;
+ getrusage( RUSAGE_SELF, p_rusage );
+ cout << CLIPRMO << "ru_maxrss: " << p_rusage->ru_maxrss << "\t(max resident set size)" << endl;
+ delete p_tmp;
+ */
+ }
+ delete p_rusage;
}
#endif
diff --git a/src/cli/cli.h b/src/cli/cli.h
index 88b99ef..2c37c17 100755
--- a/src/cli/cli.h
+++ b/src/cli/cli.h
@@ -5,11 +5,11 @@
#include <iostream>
#include <vector>
-#ifndef RUSAGE_SELF
-#define RUSAGE_SELF 0
+#ifndef RUSAGE_SELF
+#define RUSAGE_SELF 0
#endif
-#ifndef RUSAGE_CHILDREN
-#define RUSAGE_CHILDREN -1
+#ifndef RUSAGE_CHILDREN
+#define RUSAGE_CHILDREN -1
#endif
#include "../incl.h"
@@ -26,30 +26,26 @@ using namespace std;
class cli
#ifndef NCURSES
- : public thro
+: public thro
#endif
{
-
- private:
- int parse_input(string s_input);
+private:
+ int parse_input( string s_input );
public:
-cli( );
-~cli( );
+ cli( );
+ ~cli( );
#ifdef DEBUG
-
-void debug_routine();
+ void debug_routine();
#endif
-void print_rusage();
+ void print_rusage();
#ifndef NCURSES
-
-void start(void* p_void);
+ void start(void* p_void);
#else
-
-void start();
+ void start();
#endif
};
diff --git a/src/conf/conf.cpp b/src/conf/conf.cpp
index f053d85..99347e9 100755
--- a/src/conf/conf.cpp
+++ b/src/conf/conf.cpp
@@ -1,3 +1,5 @@
+// class conf implementation.
+
#ifndef CONF_CPP
#define CONF_CPP
@@ -6,140 +8,136 @@
using namespace std;
-conf::conf( string s_conf, map<string,string>* p_start_params ) : name::name( s_conf )
+conf::conf( string s_conf, map<string,string>* p_start_params ) : nmap<string,string>::nmap(HMAPOCC), name::name( s_conf )
{
- string s_check[] = {
- get_name(),
- string(getenv("HOME"))+string("/.ychat/") + get_name(),
- string("./etc/") + get_name(),
- string("/etc/") + get_name(),
- string(PREFIX+string("etc/")+get_name()) };
+ string s_check[] = {
+ get_name(),
+ string(getenv("HOME"))+string("/.yhttpd/") + get_name(),
+ string("./etc/") + get_name(),
+ string("/etc/") + get_name(),
+ string(PREFIX+string("etc/")+get_name()) };
- string s_config;
+ string s_config;
- for ( int i = 0; i < 4; ++i )
- {
- cout << "Checking for " << s_check[i];
- ifstream if_check( s_check[i].c_str() );
- if( if_check )
+ for ( int i = 0; i<4; i++ )
{
- s_config = s_check[i];
- if_check.close();
- cout << "... ok!" << endl;
- break;
+ cout << "Checking for " << s_check[i];
+ ifstream if_check( s_check[i].c_str() );
+ if( if_check )
+ {
+ s_config = s_check[i];
+ if_check.close();
+ cout << "... ok!" << endl;
+ break;
+ }
+ cout << "... not ok!" << endl;
}
- cout << "... not ok!" << endl;
- }
-
- if ( s_config.empty() )
- {
- cout << CFILEFA << endl;
- exit(1);
- }
- else
- {
- cout << CFILEOK << "..." << endl;
- }
- p_xml = new TiXmlDocument(s_config.c_str());
- TiXmlBase::SetCondenseWhiteSpace( false );
+ if ( s_config.empty() )
+ {
+ cout << CFILEFA << endl;
+ exit(1);
+ }
- if ( !p_xml->LoadFile() )
- {
- cout << XMLER1 << endl;
- exit(1);
- }
+ else
+ {
+ cout << CFILEOK << "..." << endl;
+ }
- vector<string> vec_string;
- parse_xml(p_xml, &vec_string);
+ p_xml = new TiXmlDocument(s_config.c_str());
+ TiXmlBase::SetCondenseWhiteSpace( false );
+
+ if ( !p_xml->LoadFile() )
+ {
+ cout << XMLER1 << endl;
+ exit(1);
+ }
- shashmap<string>::add_elem_insecure(tool::ychat_version(), "ychat.version");
+ vector<string> vec_string;
+ parse_xml(p_xml, &vec_string);
- // Overrides ychat.conf values with command line options (ychat -o key1 value1 -o key2 value2 ...)
- map<string,string>::iterator iter;
- for ( iter = p_start_params->begin(); iter != p_start_params->end(); iter++ )
- {
- shashmap<string>::del_elem_insecure(iter->first);
- shashmap<string>::add_elem_insecure(iter->second, iter->first);
- }
+ nmap<string,string>::add_elem_insecure(tool::yhttpd_version(), "yhttpd.version");
+
+ // Overrides yhttpd.conf values with command line options (yhttpd -o key1 value1 -o key2 value2 ...)
+ map<string,string>::iterator iter;
+ for ( iter = p_start_params->begin(); iter != p_start_params->end(); iter++ )
+ {
+ nmap<string,string>::del_elem_insecure(iter->first);
+ nmap<string,string>::add_elem_insecure(iter->second, iter->first);
+ }
- delete p_xml;
+ delete p_xml;
}
void
conf::parse_xml(TiXmlNode* p_node, vector<string>* p_vec)
{
if ( p_node->NoChildren() )
- return;
+ return;
for ( TiXmlNode* p_child = p_node->FirstChild(); p_child; p_child = p_child->NextSibling() )
{
- //cout << p_vec->size() << ": (Value:" << p_child->Value() << ") (Type:" << p_child->Type() << ")" << endl;
+ //cout << p_vec->size() << ": (Value:" << p_child->Value() << ") (Type:" << p_child->Type() << ")" << endl;
- if ( strcmp(p_child->Value(),"category") == 0 )
- {
- p_vec->push_back(p_child->ToElement()->Attribute("name"));
- parse_xml(p_child, p_vec);
- p_vec->pop_back();
- }
- else if ( strcmp(p_child->Value(),"option") == 0 )
- {
- string s_option_name = "";
+ if ( strcmp(p_child->Value(),"category") == 0)
+ {
+ p_vec->push_back(p_child->ToElement()->Attribute("name"));
+ parse_xml(p_child, p_vec);
+ p_vec->pop_back();
+ }
+
+ else if ( strcmp(p_child->Value(),"option") == 0)
+ {
+ string s_option_name = "";
- for ( vector<string>::iterator iter = p_vec->
- begin();
- iter != p_vec->end();
- ++iter )
- s_option_name.append(*iter + ".");
+ for ( vector<string>::iterator iter = p_vec->begin(); iter != p_vec->end(); ++iter )
+ s_option_name.append(*iter + ".");
- TiXmlElement* p_element = p_child->ToElement();
- exit_if_xml_error();
+ TiXmlElement* p_element = p_child->ToElement();
+ exit_if_xml_error();
- s_option_name.append(p_element->Attribute("name"));
+ s_option_name.append(p_element->Attribute("name"));
#ifdef VERBOSE
- cout << XMLREAD << s_option_name;
+ cout << XMLREAD << s_option_name;
#endif
- TiXmlNode *p_node_value = p_element->FirstChild("value");
- TiXmlNode *p_node_descr = p_element->FirstChild("descr");
+ TiXmlNode *p_node_value = p_element->FirstChild("value");
+ TiXmlNode *p_node_descr = p_element->FirstChild("descr");
- TiXmlText* p_text_value = NULL;
- TiXmlText* p_text_descr = NULL;
+ TiXmlText* p_text_value = NULL;
+ TiXmlText* p_text_descr = NULL;
- if ( p_node_value && p_node_value->FirstChild()
- )
- p_text_value = p_node_value->FirstChild()->ToText();
+ if ( p_node_value && p_node_value->FirstChild() )
+ p_text_value = p_node_value->FirstChild()->ToText();
- if ( p_node_descr && p_node_descr->FirstChild()
- )
- p_text_descr = p_node_descr->FirstChild()->ToText();
+ if ( p_node_descr && p_node_descr->FirstChild() )
+ p_text_descr = p_node_descr->FirstChild()->ToText();
- if ( !p_text_value )
- continue;
+ if ( !p_text_value )
+ continue;
#ifdef VERBOSE
- cout << " := " << p_text_value->Value() << endl;
+ cout << " := " << p_text_value->Value() << endl;
#endif
- shashmap<string>::add_elem_insecure(p_text_value->Value(), s_option_name);
+ nmap<string,string>::add_elem_insecure(p_text_value->Value(), s_option_name);
- if ( !p_text_descr )
- continue;
+ if ( !p_text_descr )
+ continue;
- s_option_name.append(".descr");
+ s_option_name.append(".descr");
#ifdef VERBOSE
- cout << XMLREAD << s_option_name << endl;
+ cout << XMLREAD << s_option_name << endl;
#endif
- shashmap<string>::add_elem_insecure(p_text_descr->Value(), s_option_name);
- }
+ nmap<string,string>::add_elem_insecure(p_text_descr->Value(), s_option_name);
+ }
}
- exit_if_xml_error()
- ;
+ exit_if_xml_error();
}
-conf::~conf()
+conf::~conf()
{
delete p_xml;
}
@@ -147,21 +145,11 @@ conf::~conf()
void
conf::exit_if_xml_error() const
{
- if ( p_xml->Error() )
- {
- cout << XMLERR << p_xml->ErrorDesc() << endl;
- exit(1);
- }
-}
-
-//<<*
-string
-conf::colored_error_msg(string s_key)
-{
- return "<font color=\"#"
- + shashmap<string>::get_elem("chat.html.errorcolor")
- + "\">" + shashmap<string>::get_elem(s_key) + "</font><br>\n";
+ if ( p_xml->Error() )
+ {
+ cout << XMLERR << p_xml->ErrorDesc() << endl;
+ exit(1);
+ }
}
-//*>>
#endif
diff --git a/src/conf/conf.h b/src/conf/conf.h
index 20aa91c..7508872 100755
--- a/src/conf/conf.h
+++ b/src/conf/conf.h
@@ -1,28 +1,27 @@
+// class conf declaration. this class parses the server config file.
+
#ifndef CONF_H
#define CONF_H
-class conf; // Predefine for nmap.tmpl
+class conf;
-#include <map>
#include "../incl.h"
-#include "../maps/shashmap.h"
+#include "../maps/nmap.h"
#include "../name.h"
#include "../contrib/xml/tinyxml.h"
using namespace std;
-class conf : public shashmap<string>, name
+class conf : public nmap<string,string>, name
{
private:
- TiXmlDocument* p_xml;
- void exit_if_xml_error() const;
- void parse_xml( TiXmlNode* p_node, vector<string>* p_vec);
-
+ TiXmlDocument* p_xml;
+ void exit_if_xml_error() const;
+ void parse_xml( TiXmlNode* p_node, vector<string>* p_vec);
public:
- conf(string s_conf, map<string,string>* p_start_params);
- ~conf();
-
- string colored_error_msg( string s_key ); //<<
+ //conf ( string s_conf );
+ conf ( string s_conf, map<string,string>* p_start_params );
+ ~conf();
};
#endif
diff --git a/src/configure b/src/configure
index 7bb48df..c68183c 100755
--- a/src/configure
+++ b/src/configure
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# The yChat Project (2003 - 2004)
+# The yhttpd Project (2003 - 2004)
#
if ! which perl >/dev/null
@@ -26,15 +26,12 @@ perl -e '
my @headers = (
"dlfcn.h",
"pthread.h",
- "mysql/mysql.h", #//<< Not needed for yhttpd
"netinet/in.h",
"time.h",
- "ncurses.h",
- "ext/hash_map"
+ "ncurses.h"
);
my @libs = (
- "libmysqlclient.so", #//<< Not needed for yhttpd
"libncurses.so"
);
@@ -76,7 +73,6 @@ perl -e '
"/include",
"/usr/include",
"/usr/local/include",
- "/usr/lib/",
"/usr/pkg/include",
"/opt/include",
"/opt/local/include"
@@ -93,14 +89,14 @@ perl -e '
"/opt/local/lib"
);
- if ( defined $ENV{YCHATHEADERPATHS} ) {
+ if ( defined $ENV{YHTTPDHEADERPATHS} ) {
map { print "Adding $_...\n";
- unshift @headerpaths, $_ } split /:/, $ENV{YCHATHEADERPATHS};
+ unshift @headerpaths, $_ } split /:/, $ENV{YHTTPDHEADERPATHS};
}
- if ( defined $ENV{YCHATLIBPATHS} ) {
+ if ( defined $ENV{YHTTPDLIBPATHS} ) {
map { print "Adding $_...\n";
- unshift @libpaths, $_ } split /:/, $ENV{YCHATLIBPATHS};
+ unshift @libpaths, $_ } split /:/, $ENV{YHTTPDLIBPATHS};
}
sub check {
@@ -142,22 +138,17 @@ perl -e '
print "NOT OK\n";
print "Please make sure that you have the needed software installed!\n";
print "If you have a special path for your includes then edit src/configure!\n";
- print "Or set the environment variables YCHATHEADERPATHS and YCHATLIBPATHS.\n";
- print " Example: setenv YCHATHEADERPATHS \"/your/header/includes:/a/includes\"\n";
+ print "Or set the environment variables YHTTPDHEADERPATHS and YHTTPDLIBPATHS.\n";
+ print " Example: setenv YHTTPDHEADERPATHS \"/your/header/includes:/a/includes\"\n";
print "(The environment variables have to be seperated by an :)\n";
- print "PS: You may use the locate and/or find command to search for files.\n";
exit(1);
}
- `touch ../err`;
return "";
}
- print "Headers:\n";
-
map { $incadd{&check($deepness, $_, @headerpaths)}++ }
@headers;
- print "Libraries:\n";
map { $libadd{&check($deepness, $_, @libpaths)}++ }
@libs;
@@ -197,16 +188,14 @@ perl -e '
my $compiler = `tail -n 1 ../g++.version`;
my $version = `tail -n 2 ../g++.version | head -n 1`;
my $uname = `uname -srm`;
- my $compopt = join "; ", split /\n/, `cat ../g++.version`;
chomp $uname;
- chomp $compopt;
print "Configuring for $uname...\n";
chomp $cpp;
chomp $version;
while (<Fin>) {
s/^(CC=).*\n/$1$compiler/;
s/^(SRCS=).*/$1$cpp/;
- s/ -frepo//; # unless $version =~ /3\.4/;
+ s/ -frepo// unless $version =~ /3\.4/;
if ( $uname !~ /Linux/i ) {
print "Disabling -ldl flag...\n" if s/ -ldl//;
}
@@ -241,7 +230,6 @@ perl -e '
open F, ">msgs.h" or die "msgs.h: $!\n";
foreach (@msgs) {
s/(UNAME)(.+)$/UNAME "$uname"/;
- s/(COMPOPT)(.+)$/COMPOPT "$compopt"/;
print F;
}
close F;
@@ -249,9 +237,7 @@ perl -e '
if ( -d "mods" ) {
chdir("mods");
my $cflags = "-fno-inline -fno-default-inline";
- $cflags .= " -nostdlib"
- if $uname =~ /FreeBSD/i
- && `uname -r` =~ /^4\./;
+ $cflags .= " -nostdlib" if $uname !~ /Linux/i;
system("echo $cflags > cflags.add");
system("./configure");
chdir("..");
diff --git a/src/contrib/README b/src/contrib/README
index 873f114..105f25d 100644
--- a/src/contrib/README
+++ b/src/contrib/README
@@ -1,5 +1,5 @@
-This directory includes source code which has been included directly into yChat but is not
-programmed by the yChat project explicitly which means the source code here is from extern.
+This directory includes source code which has been included directly into yhttpd but is not
+programmed by the yhttpd project explicitly which means the source code here is from extern.
Used versions:
tinyxml 2.3.2
diff --git a/src/contrib/xml/README b/src/contrib/xml/README
index c03aaad..7da9dfd 100644
--- a/src/contrib/xml/README
+++ b/src/contrib/xml/README
@@ -1,7 +1,7 @@
ATTENTION:
This version of TinyXML has ben very little modified by
-Paul C. Buetow in 2004 to fit the yChat project.
+Paul C. Buetow in 2004 to fit the yhttpd project.
To get the original source go to
http://www.sourceforge.net/projects/tinyxml
diff --git a/src/contrib/xml/tinyxml.cpp b/src/contrib/xml/tinyxml.cpp
index 73e57c2..dd1f471 100644
--- a/src/contrib/xml/tinyxml.cpp
+++ b/src/contrib/xml/tinyxml.cpp
@@ -1,23 +1,23 @@
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
-
+
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
-
+
3. This notice may not be removed or altered from any source
distribution.
*/
@@ -34,1395 +34,1394 @@ bool TiXmlBase::condenseWhiteSpace = true;
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
{
- TIXML_STRING buffer;
- PutString( str, &buffer );
- (*stream) << buffer;
+ TIXML_STRING buffer;
+ PutString( str, &buffer );
+ (*stream) << buffer;
}
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
{
- int i=0;
-
- while( i<(int)str.length() )
- {
- unsigned char c = (unsigned char) str[i];
-
- if ( c == '&'
- && i < ( (int)str.length() - 2 )
- && str[i+1] == '#'
- && str[i+2] == 'x' )
- {
- // Hexadecimal character reference.
- // Pass through unchanged.
- // &#xA9; -- copyright symbol, for example.
- //
- // The -1 is a bug fix from Rob Laveaux. It keeps
- // an overflow from happening if there is no ';'.
- // There are actually 2 ways to exit this loop -
- // while fails (error case) and break (semicolon found).
- // However, there is no mechanism (currently) for
- // this function to return an error.
- while ( i<(int)str.length()-1 )
- {
- outString->append( str.c_str() + i, 1 );
- ++i;
- if ( str[i] == ';' )
- break;
- }
- }
- else if ( c == '&' )
- {
- outString->append( entity[0].str, entity[0].strLength );
- ++i;
- }
- else if ( c == '<' )
- {
- outString->append( entity[1].str, entity[1].strLength );
- ++i;
- }
- else if ( c == '>' )
- {
- outString->append( entity[2].str, entity[2].strLength );
- ++i;
- }
- else if ( c == '\"' )
- {
- outString->append( entity[3].str, entity[3].strLength );
- ++i;
- }
- else if ( c == '\'' )
- {
- outString->append( entity[4].str, entity[4].strLength );
- ++i;
- }
- else if ( c < 32 )
- {
- // Easy pass at non-alpha/numeric/symbol
- // Below 32 is symbolic.
- char buf[ 32 ];
- sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
- outString->append( buf, strlen( buf ) );
- ++i;
- }
- else
- {
- //char realc = (char) c;
- //outString->append( &realc, 1 );
- *outString += (char) c; // somewhat more efficient function call.
- ++i;
- }
- }
+ int i=0;
+
+ while( i<(int)str.length() )
+ {
+ unsigned char c = (unsigned char) str[i];
+
+ if ( c == '&'
+ && i < ( (int)str.length() - 2 )
+ && str[i+1] == '#'
+ && str[i+2] == 'x' )
+ {
+ // Hexadecimal character reference.
+ // Pass through unchanged.
+ // &#xA9; -- copyright symbol, for example.
+ //
+ // The -1 is a bug fix from Rob Laveaux. It keeps
+ // an overflow from happening if there is no ';'.
+ // There are actually 2 ways to exit this loop -
+ // while fails (error case) and break (semicolon found).
+ // However, there is no mechanism (currently) for
+ // this function to return an error.
+ while ( i<(int)str.length()-1 )
+ {
+ outString->append( str.c_str() + i, 1 );
+ ++i;
+ if ( str[i] == ';' )
+ break;
+ }
+ }
+ else if ( c == '&' )
+ {
+ outString->append( entity[0].str, entity[0].strLength );
+ ++i;
+ }
+ else if ( c == '<' )
+ {
+ outString->append( entity[1].str, entity[1].strLength );
+ ++i;
+ }
+ else if ( c == '>' )
+ {
+ outString->append( entity[2].str, entity[2].strLength );
+ ++i;
+ }
+ else if ( c == '\"' )
+ {
+ outString->append( entity[3].str, entity[3].strLength );
+ ++i;
+ }
+ else if ( c == '\'' )
+ {
+ outString->append( entity[4].str, entity[4].strLength );
+ ++i;
+ }
+ else if ( c < 32 )
+ {
+ // Easy pass at non-alpha/numeric/symbol
+ // Below 32 is symbolic.
+ char buf[ 32 ];
+ sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+ outString->append( buf, strlen( buf ) );
+ ++i;
+ }
+ else
+ {
+ //char realc = (char) c;
+ //outString->append( &realc, 1 );
+ *outString += (char) c; // somewhat more efficient function call.
+ ++i;
+ }
+ }
}
// <-- Strange class for a bug fix. Search for STL_STRING_BUG
TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
{
- buffer = new char[ str.length()+1 ];
- if ( buffer )
- {
- strcpy( buffer, str.c_str() );
- }
+ buffer = new char[ str.length()+1 ];
+ if ( buffer )
+ {
+ strcpy( buffer, str.c_str() );
+ }
}
TiXmlBase::StringToBuffer::~StringToBuffer()
{
- delete [] buffer;
+ delete [] buffer;
}
// End strange bug fix. -->
TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
{
- parent = 0;
- type = _type;
- firstChild = 0;
- lastChild = 0;
- prev = 0;
- next = 0;
+ parent = 0;
+ type = _type;
+ firstChild = 0;
+ lastChild = 0;
+ prev = 0;
+ next = 0;
}
TiXmlNode::~TiXmlNode()
{
- TiXmlNode* node = firstChild;
- TiXmlNode* temp = 0;
+ TiXmlNode* node = firstChild;
+ TiXmlNode* temp = 0;
- while ( node )
- {
- temp = node;
- node = node->next;
- delete temp;
- }
+ while ( node )
+ {
+ temp = node;
+ node = node->next;
+ delete temp;
+ }
}
void TiXmlNode::CopyTo( TiXmlNode* target ) const
{
- target->SetValue (value.c_str() );
- target->userData = userData;
+ target->SetValue (value.c_str() );
+ target->userData = userData;
}
void TiXmlNode::Clear()
{
- TiXmlNode* node = firstChild;
- TiXmlNode* temp = 0;
+ TiXmlNode* node = firstChild;
+ TiXmlNode* temp = 0;
- while ( node )
- {
- temp = node;
- node = node->next;
- delete temp;
- }
+ while ( node )
+ {
+ temp = node;
+ node = node->next;
+ delete temp;
+ }
- firstChild = 0;
- lastChild = 0;
+ firstChild = 0;
+ lastChild = 0;
}
TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
{
- node->parent = this;
+ node->parent = this;
- node->prev = lastChild;
- node->next = 0;
+ node->prev = lastChild;
+ node->next = 0;
- if ( lastChild )
- lastChild->next = node;
- else
- firstChild = node; // it was an empty list.
+ if ( lastChild )
+ lastChild->next = node;
+ else
+ firstChild = node; // it was an empty list.
- lastChild = node;
- return node;
+ lastChild = node;
+ return node;
}
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
{
- TiXmlNode* node = addThis.Clone();
- if ( !node )
- return 0;
+ TiXmlNode* node = addThis.Clone();
+ if ( !node )
+ return 0;
- return LinkEndChild( node );
+ return LinkEndChild( node );
}
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
-{
- if ( !beforeThis || beforeThis->parent != this )
- return 0;
-
- TiXmlNode* node = addThis.Clone();
- if ( !node )
- return 0;
- node->parent = this;
-
- node->next = beforeThis;
- node->prev = beforeThis->prev;
- if ( beforeThis->prev )
- {
- beforeThis->prev->next = node;
- }
- else
- {
- assert( firstChild == beforeThis );
- firstChild = node;
- }
- beforeThis->prev = node;
- return node;
+{
+ if ( !beforeThis || beforeThis->parent != this )
+ return 0;
+
+ TiXmlNode* node = addThis.Clone();
+ if ( !node )
+ return 0;
+ node->parent = this;
+
+ node->next = beforeThis;
+ node->prev = beforeThis->prev;
+ if ( beforeThis->prev )
+ {
+ beforeThis->prev->next = node;
+ }
+ else
+ {
+ assert( firstChild == beforeThis );
+ firstChild = node;
+ }
+ beforeThis->prev = node;
+ return node;
}
TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
{
- if ( !afterThis || afterThis->parent != this )
- return 0;
+ if ( !afterThis || afterThis->parent != this )
+ return 0;
- TiXmlNode* node = addThis.Clone();
- if ( !node )
- return 0;
- node->parent = this;
+ TiXmlNode* node = addThis.Clone();
+ if ( !node )
+ return 0;
+ node->parent = this;
- node->prev = afterThis;
- node->next = afterThis->next;
- if ( afterThis->next )
- {
- afterThis->next->prev = node;
- }
- else
- {
- assert( lastChild == afterThis );
- lastChild = node;
- }
- afterThis->next = node;
- return node;
+ node->prev = afterThis;
+ node->next = afterThis->next;
+ if ( afterThis->next )
+ {
+ afterThis->next->prev = node;
+ }
+ else
+ {
+ assert( lastChild == afterThis );
+ lastChild = node;
+ }
+ afterThis->next = node;
+ return node;
}
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
{
- if ( replaceThis->parent != this )
- return 0;
+ if ( replaceThis->parent != this )
+ return 0;
- TiXmlNode* node = withThis.Clone();
- if ( !node )
- return 0;
+ TiXmlNode* node = withThis.Clone();
+ if ( !node )
+ return 0;
- node->next = replaceThis->next;
- node->prev = replaceThis->prev;
+ node->next = replaceThis->next;
+ node->prev = replaceThis->prev;
- if ( replaceThis->next )
- replaceThis->next->prev = node;
- else
- lastChild = node;
+ if ( replaceThis->next )
+ replaceThis->next->prev = node;
+ else
+ lastChild = node;
- if ( replaceThis->prev )
- replaceThis->prev->next = node;
- else
- firstChild = node;
+ if ( replaceThis->prev )
+ replaceThis->prev->next = node;
+ else
+ firstChild = node;
- delete replaceThis;
- node->parent = this;
- return node;
+ delete replaceThis;
+ node->parent = this;
+ return node;
}
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
{
- if ( removeThis->parent != this )
- {
- assert( 0 );
- return false;
- }
+ if ( removeThis->parent != this )
+ {
+ assert( 0 );
+ return false;
+ }
- if ( removeThis->next )
- removeThis->next->prev = removeThis->prev;
- else
- lastChild = removeThis->prev;
+ if ( removeThis->next )
+ removeThis->next->prev = removeThis->prev;
+ else
+ lastChild = removeThis->prev;
- if ( removeThis->prev )
- removeThis->prev->next = removeThis->next;
- else
- firstChild = removeThis->next;
+ if ( removeThis->prev )
+ removeThis->prev->next = removeThis->next;
+ else
+ firstChild = removeThis->next;
- delete removeThis;
- return true;
+ delete removeThis;
+ return true;
}
TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
{
- TiXmlNode* node;
- for ( node = firstChild; node; node = node->next )
- {
- if ( node->SValue() == TIXML_STRING( _value ))
- return node;
- }
- return 0;
+ TiXmlNode* node;
+ for ( node = firstChild; node; node = node->next )
+ {
+ if ( node->SValue() == TIXML_STRING( _value ))
+ return node;
+ }
+ return 0;
}
TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
{
- TiXmlNode* node;
- for ( node = lastChild; node; node = node->prev )
- {
- if ( node->SValue() == TIXML_STRING (_value))
- return node;
- }
- return 0;
+ TiXmlNode* node;
+ for ( node = lastChild; node; node = node->prev )
+ {
+ if ( node->SValue() == TIXML_STRING (_value))
+ return node;
+ }
+ return 0;
}
TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const
{
- if ( !previous )
- {
- return FirstChild();
- }
- else
- {
- assert( previous->parent == this );
- return previous->NextSibling();
- }
+ if ( !previous )
+ {
+ return FirstChild();
+ }
+ else
+ {
+ assert( previous->parent == this );
+ return previous->NextSibling();
+ }
}
TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const
{
- if ( !previous )
- {
- return FirstChild( val );
- }
- else
- {
- assert( previous->parent == this );
- return previous->NextSibling( val );
- }
+ if ( !previous )
+ {
+ return FirstChild( val );
+ }
+ else
+ {
+ assert( previous->parent == this );
+ return previous->NextSibling( val );
+ }
}
TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
{
- TiXmlNode* node;
- for ( node = next; node; node = node->next )
- {
- if ( node->SValue() == TIXML_STRING (_value))
- return node;
- }
- return 0;
+ TiXmlNode* node;
+ for ( node = next; node; node = node->next )
+ {
+ if ( node->SValue() == TIXML_STRING (_value))
+ return node;
+ }
+ return 0;
}
TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
{
- TiXmlNode* node;
- for ( node = prev; node; node = node->prev )
- {
- if ( node->SValue() == TIXML_STRING (_value))
- return node;
- }
- return 0;
+ TiXmlNode* node;
+ for ( node = prev; node; node = node->prev )
+ {
+ if ( node->SValue() == TIXML_STRING (_value))
+ return node;
+ }
+ return 0;
}
void TiXmlElement::RemoveAttribute( const char * name )
{
- TiXmlAttribute* node = attributeSet.Find( name );
- if ( node )
- {
- attributeSet.Remove( node );
- delete node;
- }
+ TiXmlAttribute* node = attributeSet.Find( name );
+ if ( node )
+ {
+ attributeSet.Remove( node );
+ delete node;
+ }
}
TiXmlElement* TiXmlNode::FirstChildElement() const
{
- TiXmlNode* node;
+ TiXmlNode* node;
- for ( node = FirstChild();
- node;
- node = node->NextSibling() )
- {
- if ( node->ToElement() )
- return node->ToElement();
- }
- return 0;
+ for ( node = FirstChild();
+ node;
+ node = node->NextSibling() )
+ {
+ if ( node->ToElement() )
+ return node->ToElement();
+ }
+ return 0;
}
TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
{
- TiXmlNode* node;
+ TiXmlNode* node;
- for ( node = FirstChild( _value );
- node;
- node = node->NextSibling( _value ) )
- {
- if ( node->ToElement() )
- return node->ToElement();
- }
- return 0;
+ for ( node = FirstChild( _value );
+ node;
+ node = node->NextSibling( _value ) )
+ {
+ if ( node->ToElement() )
+ return node->ToElement();
+ }
+ return 0;
}
TiXmlElement* TiXmlNode::NextSiblingElement() const
{
- TiXmlNode* node;
+ TiXmlNode* node;
- for ( node = NextSibling();
- node;
- node = node->NextSibling() )
- {
- if ( node->ToElement() )
- return node->ToElement();
- }
- return 0;
+ for ( node = NextSibling();
+ node;
+ node = node->NextSibling() )
+ {
+ if ( node->ToElement() )
+ return node->ToElement();
+ }
+ return 0;
}
TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
{
- TiXmlNode* node;
+ TiXmlNode* node;
- for ( node = NextSibling( _value );
- node;
- node = node->NextSibling( _value ) )
- {
- if ( node->ToElement() )
- return node->ToElement();
- }
- return 0;
+ for ( node = NextSibling( _value );
+ node;
+ node = node->NextSibling( _value ) )
+ {
+ if ( node->ToElement() )
+ return node->ToElement();
+ }
+ return 0;
}
TiXmlDocument* TiXmlNode::GetDocument() const
{
- const TiXmlNode* node;
+ const TiXmlNode* node;
- for( node = this; node; node = node->parent )
- {
- if ( node->ToDocument() )
- return node->ToDocument();
- }
- return 0;
+ for( node = this; node; node = node->parent )
+ {
+ if ( node->ToDocument() )
+ return node->ToDocument();
+ }
+ return 0;
}
TiXmlElement::TiXmlElement (const char * _value)
- : TiXmlNode( TiXmlNode::ELEMENT )
+ : TiXmlNode( TiXmlNode::ELEMENT )
{
- firstChild = lastChild = 0;
- value = _value;
+ firstChild = lastChild = 0;
+ value = _value;
}
#ifdef TIXML_USE_STL
-TiXmlElement::TiXmlElement( const std::string& _value )
- : TiXmlNode( TiXmlNode::ELEMENT )
+TiXmlElement::TiXmlElement( const std::string& _value )
+ : TiXmlNode( TiXmlNode::ELEMENT )
{
- firstChild = lastChild = 0;
- value = _value;
+ firstChild = lastChild = 0;
+ value = _value;
}
#endif
TiXmlElement::TiXmlElement( const TiXmlElement& copy)
- : TiXmlNode( TiXmlNode::ELEMENT )
+ : TiXmlNode( TiXmlNode::ELEMENT )
{
- firstChild = lastChild = 0;
- copy.CopyTo( this );
+ firstChild = lastChild = 0;
+ copy.CopyTo( this );
}
void TiXmlElement::operator=( const TiXmlElement& base )
{
- ClearThis();
- base.CopyTo( this );
+ ClearThis();
+ base.CopyTo( this );
}
TiXmlElement::~TiXmlElement()
{
- ClearThis();
+ ClearThis();
}
void TiXmlElement::ClearThis()
{
- Clear();
- while( attributeSet.First() )
- {
- TiXmlAttribute* node = attributeSet.First();
- attributeSet.Remove( node );
- delete node;
- }
+ Clear();
+ while( attributeSet.First() )
+ {
+ TiXmlAttribute* node = attributeSet.First();
+ attributeSet.Remove( node );
+ delete node;
+ }
}
const char * TiXmlElement::Attribute( const char * name ) const
{
- TiXmlAttribute* node = attributeSet.Find( name );
+ TiXmlAttribute* node = attributeSet.Find( name );
- if ( node )
- return node->Value();
+ if ( node )
+ return node->Value();
- return 0;
+ return 0;
}
const char * TiXmlElement::Attribute( const char * name, int* i ) const
{
- const char * s = Attribute( name );
- if ( i )
- {
- if ( s )
- *i = atoi( s );
- else
- *i = 0;
- }
- return s;
+ const char * s = Attribute( name );
+ if ( i )
+ {
+ if ( s )
+ *i = atoi( s );
+ else
+ *i = 0;
+ }
+ return s;
}
const char * TiXmlElement::Attribute( const char * name, double* d ) const
{
- const char * s = Attribute( name );
- if ( d )
- {
- if ( s )
- *d = atof( s );
- else
- *d = 0;
- }
- return s;
+ const char * s = Attribute( name );
+ if ( d )
+ {
+ if ( s )
+ *d = atof( s );
+ else
+ *d = 0;
+ }
+ return s;
}
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
{
- TiXmlAttribute* node = attributeSet.Find( name );
- if ( !node )
- return TIXML_NO_ATTRIBUTE;
+ TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
- return node->QueryIntValue( ival );
+ return node->QueryIntValue( ival );
}
int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
{
- TiXmlAttribute* node = attributeSet.Find( name );
- if ( !node )
- return TIXML_NO_ATTRIBUTE;
+ TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
- return node->QueryDoubleValue( dval );
+ return node->QueryDoubleValue( dval );
}
void TiXmlElement::SetAttribute( const char * name, int val )
-{
- char buf[64];
- sprintf( buf, "%d", val );
- SetAttribute( name, buf );
+{
+ char buf[64];
+ sprintf( buf, "%d", val );
+ SetAttribute( name, buf );
}
void TiXmlElement::SetDoubleAttribute( const char * name, double val )
-{
- char buf[128];
- sprintf( buf, "%f", val );
- SetAttribute( name, buf );
+{
+ char buf[128];
+ sprintf( buf, "%f", val );
+ SetAttribute( name, buf );
}
void TiXmlElement::SetAttribute( const char * name, const char * _value )
{
- TiXmlAttribute* node = attributeSet.Find( name );
- if ( node )
- {
- node->SetValue( _value );
- return;
- }
-
- TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
- if ( attrib )
- {
- attributeSet.Add( attrib );
- }
- else
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
- }
+ TiXmlAttribute* node = attributeSet.Find( name );
+ if ( node )
+ {
+ node->SetValue( _value );
+ return;
+ }
+
+ TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+ if ( attrib )
+ {
+ attributeSet.Add( attrib );
+ }
+ else
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+ }
}
void TiXmlElement::Print( FILE* cfile, int depth ) const
{
- int i;
- for ( i=0; i<depth; i++ )
- {
- fprintf( cfile, " " );
- }
-
- fprintf( cfile, "<%s", value.c_str() );
-
- TiXmlAttribute* attrib;
- for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
- {
- fprintf( cfile, " " );
- attrib->Print( cfile, depth );
- }
-
- // There are 3 different formatting approaches:
- // 1) An element without children is printed as a <foo /> node
- // 2) An element with only a text child is printed as <foo> text </foo>
- // 3) An element with children is printed on multiple lines.
- TiXmlNode* node;
- if ( !firstChild )
- {
- fprintf( cfile, " />" );
- }
- else if ( firstChild == lastChild && firstChild->ToText() )
- {
- fprintf( cfile, ">" );
- firstChild->Print( cfile, depth + 1 );
- fprintf( cfile, "</%s>", value.c_str() );
- }
- else
- {
- fprintf( cfile, ">" );
-
- for ( node = firstChild; node; node=node->NextSibling() )
- {
- if ( !node->ToText() )
- {
- fprintf( cfile, "\n" );
- }
- node->Print( cfile, depth+1 );
- }
- fprintf( cfile, "\n" );
- for( i=0; i<depth; ++i )
- fprintf( cfile, " " );
- fprintf( cfile, "</%s>", value.c_str() );
- }
+ int i;
+ for ( i=0; i<depth; i++ )
+ {
+ fprintf( cfile, " " );
+ }
+
+ fprintf( cfile, "<%s", value.c_str() );
+
+ TiXmlAttribute* attrib;
+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+ {
+ fprintf( cfile, " " );
+ attrib->Print( cfile, depth );
+ }
+
+ // There are 3 different formatting approaches:
+ // 1) An element without children is printed as a <foo /> node
+ // 2) An element with only a text child is printed as <foo> text </foo>
+ // 3) An element with children is printed on multiple lines.
+ TiXmlNode* node;
+ if ( !firstChild )
+ {
+ fprintf( cfile, " />" );
+ }
+ else if ( firstChild == lastChild && firstChild->ToText() )
+ {
+ fprintf( cfile, ">" );
+ firstChild->Print( cfile, depth + 1 );
+ fprintf( cfile, "</%s>", value.c_str() );
+ }
+ else
+ {
+ fprintf( cfile, ">" );
+
+ for ( node = firstChild; node; node=node->NextSibling() )
+ {
+ if ( !node->ToText() )
+ {
+ fprintf( cfile, "\n" );
+ }
+ node->Print( cfile, depth+1 );
+ }
+ fprintf( cfile, "\n" );
+ for( i=0; i<depth; ++i )
+ fprintf( cfile, " " );
+ fprintf( cfile, "</%s>", value.c_str() );
+ }
}
void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
{
- (*stream) << "<" << value;
+ (*stream) << "<" << value;
- TiXmlAttribute* attrib;
- for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
- {
- (*stream) << " ";
- attrib->StreamOut( stream );
- }
+ TiXmlAttribute* attrib;
+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+ {
+ (*stream) << " ";
+ attrib->StreamOut( stream );
+ }
- // If this node has children, give it a closing tag. Else
- // make it an empty tag.
- TiXmlNode* node;
- if ( firstChild )
- {
- (*stream) << ">";
+ // If this node has children, give it a closing tag. Else
+ // make it an empty tag.
+ TiXmlNode* node;
+ if ( firstChild )
+ {
+ (*stream) << ">";
- for ( node = firstChild; node; node=node->NextSibling() )
- {
- node->StreamOut( stream );
- }
- (*stream) << "</" << value << ">";
- }
- else
- {
- (*stream) << " />";
- }
+ for ( node = firstChild; node; node=node->NextSibling() )
+ {
+ node->StreamOut( stream );
+ }
+ (*stream) << "</" << value << ">";
+ }
+ else
+ {
+ (*stream) << " />";
+ }
}
void TiXmlElement::CopyTo( TiXmlElement* target ) const
{
- // superclass:
- TiXmlNode::CopyTo( target );
+ // superclass:
+ TiXmlNode::CopyTo( target );
- // Element class:
- // Clone the attributes, then clone the children.
- TiXmlAttribute* attribute = 0;
- for( attribute = attributeSet.First();
- attribute;
- attribute = attribute->Next() )
- {
- target->SetAttribute( attribute->Name(), attribute->Value() );
- }
+ // Element class:
+ // Clone the attributes, then clone the children.
+ TiXmlAttribute* attribute = 0;
+ for( attribute = attributeSet.First();
+ attribute;
+ attribute = attribute->Next() )
+ {
+ target->SetAttribute( attribute->Name(), attribute->Value() );
+ }
- TiXmlNode* node = 0;
- for ( node = firstChild; node; node = node->NextSibling() )
- {
- target->LinkEndChild( node->Clone() );
- }
+ TiXmlNode* node = 0;
+ for ( node = firstChild; node; node = node->NextSibling() )
+ {
+ target->LinkEndChild( node->Clone() );
+ }
}
TiXmlNode* TiXmlElement::Clone() const
{
- TiXmlElement* clone = new TiXmlElement( Value() );
- if ( !clone )
- return 0;
+ TiXmlElement* clone = new TiXmlElement( Value() );
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
{
- tabsize = 4;
- ClearError();
+ tabsize = 4;
+ ClearError();
}
TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
{
- tabsize = 4;
- value = documentName;
- ClearError();
+ tabsize = 4;
+ value = documentName;
+ ClearError();
}
#ifdef TIXML_USE_STL
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
{
- tabsize = 4;
- value = documentName;
- ClearError();
+ tabsize = 4;
+ value = documentName;
+ ClearError();
}
#endif
TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
{
- copy.CopyTo( this );
+ copy.CopyTo( this );
}
void TiXmlDocument::operator=( const TiXmlDocument& copy )
{
- Clear();
- copy.CopyTo( this );
+ Clear();
+ copy.CopyTo( this );
}
bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
{
- // See STL_STRING_BUG below.
- StringToBuffer buf( value );
+ // See STL_STRING_BUG below.
+ StringToBuffer buf( value );
- if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
- return true;
+ if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
+ return true;
- return false;
+ return false;
}
bool TiXmlDocument::SaveFile() const
{
- // See STL_STRING_BUG below.
- StringToBuffer buf( value );
+ // See STL_STRING_BUG below.
+ StringToBuffer buf( value );
- if ( buf.buffer && SaveFile( buf.buffer ) )
- return true;
+ if ( buf.buffer && SaveFile( buf.buffer ) )
+ return true;
- return false;
+ return false;
}
bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
{
- // Delete the existing data:
- Clear();
- location.Clear();
-
- // There was a really terrifying little bug here. The code:
- // value = filename
- // in the STL case, cause the assignment method of the std::string to
- // be called. What is strange, is that the std::string had the same
- // address as it's c_str() method, and so bad things happen. Looks
- // like a bug in the Microsoft STL implementation.
- // See STL_STRING_BUG above.
- // Fixed with the StringToBuffer class.
- value = filename;
-
- FILE* file = fopen( value.c_str (), "r" );
-
- if ( file )
- {
- // 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 )
- {
- fclose( file );
- 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 );
-
- const int BUF_SIZE = 2048;
- char buf[BUF_SIZE];
-
- while( fgets( buf, BUF_SIZE, file ) )
- {
- data += buf;
- }
- fclose( file );
-
- Parse( data.c_str(), 0, encoding );
-
- if ( Error() )
- return false;
- else
- return true;
- }
- SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
- return false;
+ // Delete the existing data:
+ Clear();
+ location.Clear();
+
+ // There was a really terrifying little bug here. The code:
+ // value = filename
+ // in the STL case, cause the assignment method of the std::string to
+ // be called. What is strange, is that the std::string had the same
+ // address as it's c_str() method, and so bad things happen. Looks
+ // like a bug in the Microsoft STL implementation.
+ // See STL_STRING_BUG above.
+ // Fixed with the StringToBuffer class.
+ value = filename;
+
+ FILE* file = fopen( value.c_str (), "r" );
+
+ if ( file )
+ {
+ // 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 )
+ {
+ fclose( file );
+ 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 );
+
+ const int BUF_SIZE = 2048;
+ char buf[BUF_SIZE];
+
+ while( fgets( buf, BUF_SIZE, file ) )
+ {
+ data += buf;
+ }
+ fclose( file );
+
+ Parse( data.c_str(), 0, encoding );
+
+ if ( Error() )
+ return false;
+ else
+ return true;
+ }
+ SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return false;
}
bool TiXmlDocument::SaveFile( const char * filename ) const
{
- // The old c stuff lives on...
- FILE* fp = fopen( filename, "w" );
- if ( fp )
- {
- Print( fp, 0 );
- fclose( fp );
- return true;
- }
- return false;
+ // The old c stuff lives on...
+ FILE* fp = fopen( filename, "w" );
+ if ( fp )
+ {
+ Print( fp, 0 );
+ fclose( fp );
+ return true;
+ }
+ return false;
}
void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
{
- TiXmlNode::CopyTo( target );
+ TiXmlNode::CopyTo( target );
- target->error = error;
- target->errorDesc = errorDesc.c_str ();
+ target->error = error;
+ target->errorDesc = errorDesc.c_str ();
- TiXmlNode* node = 0;
- for ( node = firstChild; node; node = node->NextSibling() )
- {
- target->LinkEndChild( node->Clone() );
- }
+ TiXmlNode* node = 0;
+ for ( node = firstChild; node; node = node->NextSibling() )
+ {
+ target->LinkEndChild( node->Clone() );
+ }
}
TiXmlNode* TiXmlDocument::Clone() const
{
- TiXmlDocument* clone = new TiXmlDocument();
- if ( !clone )
- return 0;
+ TiXmlDocument* clone = new TiXmlDocument();
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
void TiXmlDocument::Print( FILE* cfile, int depth ) const
{
- TiXmlNode* node;
- for ( node=FirstChild(); node; node=node->NextSibling() )
- {
- node->Print( cfile, depth );
- fprintf( cfile, "\n" );
- }
+ TiXmlNode* node;
+ for ( node=FirstChild(); node; node=node->NextSibling() )
+ {
+ node->Print( cfile, depth );
+ fprintf( cfile, "\n" );
+ }
}
void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
{
- TiXmlNode* node;
- for ( node=FirstChild(); node; node=node->NextSibling() )
- {
- node->StreamOut( out );
+ TiXmlNode* node;
+ for ( node=FirstChild(); node; node=node->NextSibling() )
+ {
+ node->StreamOut( out );
- // Special rule for streams: stop after the root element.
- // The stream in code will only read one element, so don't
- // write more than one.
- if ( node->ToElement() )
- break;
- }
+ // Special rule for streams: stop after the root element.
+ // The stream in code will only read one element, so don't
+ // write more than one.
+ if ( node->ToElement() )
+ break;
+ }
}
TiXmlAttribute* TiXmlAttribute::Next() const
{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if ( next->value.empty() && next->name.empty() )
- return 0;
- return next;
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if ( next->value.empty() && next->name.empty() )
+ return 0;
+ return next;
}
TiXmlAttribute* TiXmlAttribute::Previous() const
{
- // We are using knowledge of the sentinel. The sentinel
- // have a value or name.
- if ( prev->value.empty() && prev->name.empty() )
- return 0;
- return prev;
+ // We are using knowledge of the sentinel. The sentinel
+ // have a value or name.
+ if ( prev->value.empty() && prev->name.empty() )
+ return 0;
+ return prev;
}
void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
{
- TIXML_STRING n, v;
+ TIXML_STRING n, v;
- PutString( name, &n );
- PutString( value, &v );
+ PutString( name, &n );
+ PutString( value, &v );
- if (value.find ('\"') == TIXML_STRING::npos)
- fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
- else
- fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+ if (value.find ('\"') == TIXML_STRING::npos)
+ fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+ else
+ fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
}
void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
{
- if (value.find( '\"' ) != TIXML_STRING::npos)
- {
- PutString( name, stream );
- (*stream) << "=" << "'";
- PutString( value, stream );
- (*stream) << "'";
- }
- else
- {
- PutString( name, stream );
- (*stream) << "=" << "\"";
- PutString( value, stream );
- (*stream) << "\"";
- }
+ if (value.find( '\"' ) != TIXML_STRING::npos)
+ {
+ PutString( name, stream );
+ (*stream) << "=" << "'";
+ PutString( value, stream );
+ (*stream) << "'";
+ }
+ else
+ {
+ PutString( name, stream );
+ (*stream) << "=" << "\"";
+ PutString( value, stream );
+ (*stream) << "\"";
+ }
}
int TiXmlAttribute::QueryIntValue( int* ival ) const
{
- if ( sscanf( value.c_str(), "%d", ival ) == 1 )
- return TIXML_SUCCESS;
- return TIXML_WRONG_TYPE;
+ if ( sscanf( value.c_str(), "%d", ival ) == 1 )
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
}
int TiXmlAttribute::QueryDoubleValue( double* dval ) const
{
- if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
- return TIXML_SUCCESS;
- return TIXML_WRONG_TYPE;
+ if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
}
void TiXmlAttribute::SetIntValue( int _value )
{
- char buf [64];
- sprintf (buf, "%d", _value);
- SetValue (buf);
+ char buf [64];
+ sprintf (buf, "%d", _value);
+ SetValue (buf);
}
void TiXmlAttribute::SetDoubleValue( double _value )
{
- char buf [64];
- sprintf (buf, "%lf", _value);
- SetValue (buf);
+ char buf [64];
+ sprintf (buf, "%lf", _value);
+ SetValue (buf);
}
const int TiXmlAttribute::IntValue() const
{
- return atoi (value.c_str ());
+ return atoi (value.c_str ());
}
const double TiXmlAttribute::DoubleValue() const
{
- return atof (value.c_str ());
+ return atof (value.c_str ());
}
TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
{
- copy.CopyTo( this );
+ copy.CopyTo( this );
}
void TiXmlComment::operator=( const TiXmlComment& base )
{
- Clear();
- base.CopyTo( this );
+ Clear();
+ base.CopyTo( this );
}
void TiXmlComment::Print( FILE* cfile, int depth ) const
{
- for ( int i=0; i<depth; i++ )
- {
- fputs( " ", cfile );
- }
- fprintf( cfile, "<!--%s-->", value.c_str() );
+ for ( int i=0; i<depth; i++ )
+ {
+ fputs( " ", cfile );
+ }
+ fprintf( cfile, "<!--%s-->", value.c_str() );
}
void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
{
- (*stream) << "<!--";
- //PutString( value, stream );
- (*stream) << value;
- (*stream) << "-->";
+ (*stream) << "<!--";
+ //PutString( value, stream );
+ (*stream) << value;
+ (*stream) << "-->";
}
void TiXmlComment::CopyTo( TiXmlComment* target ) const
{
- TiXmlNode::CopyTo( target );
+ TiXmlNode::CopyTo( target );
}
TiXmlNode* TiXmlComment::Clone() const
{
- TiXmlComment* clone = new TiXmlComment();
+ TiXmlComment* clone = new TiXmlComment();
- if ( !clone )
- return 0;
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const
{
- TIXML_STRING buffer;
- PutString( value, &buffer );
- fprintf( cfile, "%s", buffer.c_str() );
+ TIXML_STRING buffer;
+ PutString( value, &buffer );
+ fprintf( cfile, "%s", buffer.c_str() );
}
void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
{
- PutString( value, stream );
+ PutString( value, stream );
}
void TiXmlText::CopyTo( TiXmlText* target ) const
{
- TiXmlNode::CopyTo( target );
+ TiXmlNode::CopyTo( target );
}
TiXmlNode* TiXmlText::Clone() const
-{
- TiXmlText* clone = 0;
- clone = new TiXmlText( "" );
+{
+ TiXmlText* clone = 0;
+ clone = new TiXmlText( "" );
- if ( !clone )
- return 0;
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
TiXmlDeclaration::TiXmlDeclaration( const char * _version,
- const char * _encoding,
- const char * _standalone )
- : TiXmlNode( TiXmlNode::DECLARATION )
+ const char * _encoding,
+ const char * _standalone )
+ : TiXmlNode( TiXmlNode::DECLARATION )
{
- version = _version;
- encoding = _encoding;
- standalone = _standalone;
+ version = _version;
+ encoding = _encoding;
+ standalone = _standalone;
}
#ifdef TIXML_USE_STL
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
- const std::string& _encoding,
- const std::string& _standalone )
- : TiXmlNode( TiXmlNode::DECLARATION )
+ const std::string& _encoding,
+ const std::string& _standalone )
+ : TiXmlNode( TiXmlNode::DECLARATION )
{
- version = _version;
- encoding = _encoding;
- standalone = _standalone;
+ version = _version;
+ encoding = _encoding;
+ standalone = _standalone;
}
#endif
TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
- : TiXmlNode( TiXmlNode::DECLARATION )
+ : TiXmlNode( TiXmlNode::DECLARATION )
{
- copy.CopyTo( this );
+ copy.CopyTo( this );
}
void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
{
- Clear();
- copy.CopyTo( this );
+ Clear();
+ copy.CopyTo( this );
}
void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
{
- fprintf (cfile, "<?xml ");
+ fprintf (cfile, "<?xml ");
- if ( !version.empty() )
- fprintf (cfile, "version=\"%s\" ", version.c_str ());
- if ( !encoding.empty() )
- fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
- if ( !standalone.empty() )
- fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
- fprintf (cfile, "?>");
+ if ( !version.empty() )
+ fprintf (cfile, "version=\"%s\" ", version.c_str ());
+ if ( !encoding.empty() )
+ fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+ if ( !standalone.empty() )
+ fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+ fprintf (cfile, "?>");
}
void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
{
- (*stream) << "<?xml ";
-
- if ( !version.empty() )
- {
- (*stream) << "version=\"";
- PutString( version, stream );
- (*stream) << "\" ";
- }
- if ( !encoding.empty() )
- {
- (*stream) << "encoding=\"";
- PutString( encoding, stream );
- (*stream ) << "\" ";
- }
- if ( !standalone.empty() )
- {
- (*stream) << "standalone=\"";
- PutString( standalone, stream );
- (*stream) << "\" ";
- }
- (*stream) << "?>";
+ (*stream) << "<?xml ";
+
+ if ( !version.empty() )
+ {
+ (*stream) << "version=\"";
+ PutString( version, stream );
+ (*stream) << "\" ";
+ }
+ if ( !encoding.empty() )
+ {
+ (*stream) << "encoding=\"";
+ PutString( encoding, stream );
+ (*stream ) << "\" ";
+ }
+ if ( !standalone.empty() )
+ {
+ (*stream) << "standalone=\"";
+ PutString( standalone, stream );
+ (*stream) << "\" ";
+ }
+ (*stream) << "?>";
}
void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
{
- TiXmlNode::CopyTo( target );
+ TiXmlNode::CopyTo( target );
- target->version = version;
- target->encoding = encoding;
- target->standalone = standalone;
+ target->version = version;
+ target->encoding = encoding;
+ target->standalone = standalone;
}
TiXmlNode* TiXmlDeclaration::Clone() const
-{
- TiXmlDeclaration* clone = new TiXmlDeclaration();
+{
+ TiXmlDeclaration* clone = new TiXmlDeclaration();
- if ( !clone )
- return 0;
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
void TiXmlUnknown::Print( FILE* cfile, int depth ) const
{
- for ( int i=0; i<depth; i++ )
- fprintf( cfile, " " );
- fprintf( cfile, "<%s>", value.c_str() );
+ for ( int i=0; i<depth; i++ )
+ fprintf( cfile, " " );
+ fprintf( cfile, "<%s>", value.c_str() );
}
void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
{
- (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown.
+ (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown.
}
void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
{
- TiXmlNode::CopyTo( target );
+ TiXmlNode::CopyTo( target );
}
TiXmlNode* TiXmlUnknown::Clone() const
{
- TiXmlUnknown* clone = new TiXmlUnknown();
+ TiXmlUnknown* clone = new TiXmlUnknown();
- if ( !clone )
- return 0;
+ if ( !clone )
+ return 0;
- CopyTo( clone );
- return clone;
+ CopyTo( clone );
+ return clone;
}
TiXmlAttributeSet::TiXmlAttributeSet()
{
- sentinel.next = &sentinel;
- sentinel.prev = &sentinel;
+ sentinel.next = &sentinel;
+ sentinel.prev = &sentinel;
}
TiXmlAttributeSet::~TiXmlAttributeSet()
{
- assert( sentinel.next == &sentinel );
- assert( sentinel.prev == &sentinel );
+ assert( sentinel.next == &sentinel );
+ assert( sentinel.prev == &sentinel );
}
void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
{
- assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
+ assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
- addMe->next = &sentinel;
- addMe->prev = sentinel.prev;
+ addMe->next = &sentinel;
+ addMe->prev = sentinel.prev;
- sentinel.prev->next = addMe;
- sentinel.prev = addMe;
+ sentinel.prev->next = addMe;
+ sentinel.prev = addMe;
}
void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
{
- TiXmlAttribute* node;
+ TiXmlAttribute* node;
- for( node = sentinel.next; node != &sentinel; node = node->next )
- {
- if ( node == removeMe )
- {
- node->prev->next = node->next;
- node->next->prev = node->prev;
- node->next = 0;
- node->prev = 0;
- return;
- }
- }
- assert( 0 ); // we tried to remove a non-linked attribute.
+ for( node = sentinel.next; node != &sentinel; node = node->next )
+ {
+ if ( node == removeMe )
+ {
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ node->next = 0;
+ node->prev = 0;
+ return;
+ }
+ }
+ assert( 0 ); // we tried to remove a non-linked attribute.
}
TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
{
- TiXmlAttribute* node;
+ TiXmlAttribute* node;
- for( node = sentinel.next; node != &sentinel; node = node->next )
- {
- if ( node->name == name )
- return node;
- }
- return 0;
+ for( node = sentinel.next; node != &sentinel; node = node->next )
+ {
+ if ( node->name == name )
+ return node;
+ }
+ return 0;
}
-#ifdef TIXML_USE_STL
+#ifdef TIXML_USE_STL
TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
{
- TIXML_STRING tag;
- tag.reserve( 8 * 1000 );
- base.StreamIn( &in, &tag );
+ TIXML_STRING tag;
+ tag.reserve( 8 * 1000 );
+ base.StreamIn( &in, &tag );
- base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
- return in;
+ base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+ return in;
}
#endif
TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
{
- base.StreamOut (& out);
- return out;
+ base.StreamOut (& out);
+ return out;
}
-#ifdef TIXML_USE_STL
+#ifdef TIXML_USE_STL
std::string & operator<< (std::string& out, const TiXmlNode& base )
{
- std::ostringstream os_stream( std::ostringstream::out );
- base.StreamOut( &os_stream );
-
- out.append( os_stream.str() );
- return out;
+ std::ostringstream os_stream( std::ostringstream::out );
+ base.StreamOut( &os_stream );
+
+ out.append( os_stream.str() );
+ return out;
}
#endif
TiXmlHandle TiXmlHandle::FirstChild() const
{
- if ( node )
- {
- TiXmlNode* child = node->FirstChild();
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ TiXmlNode* child = node->FirstChild();
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
{
- if ( node )
- {
- TiXmlNode* child = node->FirstChild( value );
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ TiXmlNode* child = node->FirstChild( value );
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChildElement() const
{
- if ( node )
- {
- TiXmlElement* child = node->FirstChildElement();
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ TiXmlElement* child = node->FirstChildElement();
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
{
- if ( node )
- {
- TiXmlElement* child = node->FirstChildElement( value );
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ TiXmlElement* child = node->FirstChildElement( value );
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::Child( int count ) const
{
- if ( node )
- {
- int i;
- TiXmlNode* child = node->FirstChild();
- for ( i=0;
- child && i<count;
- child = child->NextSibling(), ++i )
- {
- // nothing
- }
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ int i;
+ TiXmlNode* child = node->FirstChild();
+ for ( i=0;
+ child && i<count;
+ child = child->NextSibling(), ++i )
+ {
+ // nothing
+ }
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
{
- if ( node )
- {
- int i;
- TiXmlNode* child = node->FirstChild( value );
- for ( i=0;
- child && i<count;
- child = child->NextSibling( value ), ++i )
- {
- // nothing
- }
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ int i;
+ TiXmlNode* child = node->FirstChild( value );
+ for ( i=0;
+ child && i<count;
+ child = child->NextSibling( value ), ++i )
+ {
+ // nothing
+ }
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::ChildElement( int count ) const
{
- if ( node )
- {
- int i;
- TiXmlElement* child = node->FirstChildElement();
- for ( i=0;
- child && i<count;
- child = child->NextSiblingElement(), ++i )
- {
- // nothing
- }
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ int i;
+ TiXmlElement* child = node->FirstChildElement();
+ for ( i=0;
+ child && i<count;
+ child = child->NextSiblingElement(), ++i )
+ {
+ // nothing
+ }
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
{
- if ( node )
- {
- int i;
- TiXmlElement* child = node->FirstChildElement( value );
- for ( i=0;
- child && i<count;
- child = child->NextSiblingElement( value ), ++i )
- {
- // nothing
- }
- if ( child )
- return TiXmlHandle( child );
- }
- return TiXmlHandle( 0 );
+ if ( node )
+ {
+ int i;
+ TiXmlElement* child = node->FirstChildElement( value );
+ for ( i=0;
+ child && i<count;
+ child = child->NextSiblingElement( value ), ++i )
+ {
+ // nothing
+ }
+ if ( child )
+ return TiXmlHandle( child );
+ }
+ return TiXmlHandle( 0 );
}
diff --git a/src/contrib/xml/tinyxml.h b/src/contrib/xml/tinyxml.h
index a9ece4b..678bdb9 100644
--- a/src/contrib/xml/tinyxml.h
+++ b/src/contrib/xml/tinyxml.h
@@ -4,23 +4,23 @@
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
-
+
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
-
+
3. This notice may not be removed or altered from any source
distribution.
*/
@@ -71,40 +71,34 @@ const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 3;
const int TIXML_PATCH_VERSION = 2;
-/* Internal structure for tracking location of items
+/* Internal structure for tracking location of items
in the XML file.
*/
struct TiXmlCursor
{
- TiXmlCursor()
- {
- Clear();
- }
- void Clear()
- {
- row = col = -1;
- }
-
- int row; // 0 based.
- int col; // 0 based.
+ TiXmlCursor() { Clear(); }
+ void Clear() { row = col = -1; }
+
+ int row; // 0 based.
+ int col; // 0 based.
};
// Only used by Attribute::Query functions
-enum
-{
- TIXML_SUCCESS,
- TIXML_NO_ATTRIBUTE,
- TIXML_WRONG_TYPE
+enum
+{
+ TIXML_SUCCESS,
+ TIXML_NO_ATTRIBUTE,
+ TIXML_WRONG_TYPE
};
// Used by the parsing routines.
enum TiXmlEncoding
{
- TIXML_ENCODING_UNKNOWN,
- TIXML_ENCODING_UTF8,
- TIXML_ENCODING_LEGACY
+ TIXML_ENCODING_UNKNOWN,
+ TIXML_ENCODING_UTF8,
+ TIXML_ENCODING_LEGACY
};
const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
@@ -112,263 +106,241 @@ const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
/** TiXmlBase is a base class for every class in TinyXml.
It does little except to establish that TinyXml classes
can be printed and provide some utility functions.
-
+
In XML, the document and elements can contain
other elements and other types of nodes.
-
+
@verbatim
A Document can contain: Element (container or leaf)
Comment (leaf)
Unknown (leaf)
Declaration( leaf )
-
+
An Element can contain: Element (container or leaf)
Text (leaf)
Attributes (not on tree)
Comment (leaf)
Unknown (leaf)
-
+
A Decleration contains: Attributes (not on tree)
@endverbatim
*/
class TiXmlBase
{
- friend class TiXmlNode;
- friend class TiXmlElement;
- friend class TiXmlDocument;
+ friend class TiXmlNode;
+ friend class TiXmlElement;
+ friend class TiXmlDocument;
public:
- TiXmlBase() : userData(0)
- {}
- virtual ~TiXmlBase()
- {}
-
- /** All TinyXml classes can print themselves to a filestream.
- This is a formatted print, and will insert tabs and newlines.
-
- (For an unformatted stream, use the << operator.)
- */
- virtual void Print( FILE* cfile, int depth ) const = 0;
-
- /** The world does not agree on whether white space should be kept or
- not. In order to make everyone happy, these global, static functions
- are provided to set whether or not TinyXml will condense all white space
- into a single space or not. The default is to condense. Note changing this
- values is not thread safe.
- */
- static void SetCondenseWhiteSpace( bool condense )
- {
- condenseWhiteSpace = condense;
- }
-
- /// Return the current white space setting.
- static bool IsWhiteSpaceCondensed()
- {
- return condenseWhiteSpace;
- }
-
- /** Return the position, in the original source file, of this node or attribute.
- The row and column are 1-based. (That is the first row and first column is
- 1,1). If the returns values are 0 or less, then the parser does not have
- a row and column value.
-
- Generally, the row and column value will be set when the TiXmlDocument::Load(),
- TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
- when the DOM was created from operator>>.
-
- The values reflect the initial load. Once the DOM is modified programmatically
- (by adding or changing nodes and attributes) the new values will NOT update to
- reflect changes in the document.
-
- There is a minor performance cost to computing the row and column. Computation
- can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
-
- @sa TiXmlDocument::SetTabSize()
- */
- int Row() const
- {
- return location.row + 1;
- }
- int Column() const
- {
- return location.col + 1;
- } ///< See Row()
-
- void SetUserData( void* user )
- {
- userData = user;
- }
- void* GetUserData()
- {
- return userData;
- }
-
- // Table that returs, for a given lead byte, the total number of bytes
- // in the UTF-8 sequence.
- static const int utf8ByteTable[256];
-
- virtual const char* Parse( const char* p,
- TiXmlParsingData* data,
- TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+ TiXmlBase() : userData(0) {}
+ virtual ~TiXmlBase() {}
+
+ /** All TinyXml classes can print themselves to a filestream.
+ This is a formatted print, and will insert tabs and newlines.
+
+ (For an unformatted stream, use the << operator.)
+ */
+ virtual void Print( FILE* cfile, int depth ) const = 0;
+
+ /** The world does not agree on whether white space should be kept or
+ not. In order to make everyone happy, these global, static functions
+ are provided to set whether or not TinyXml will condense all white space
+ into a single space or not. The default is to condense. Note changing this
+ values is not thread safe.
+ */
+ static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
+
+ /// Return the current white space setting.
+ static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
+
+ /** Return the position, in the original source file, of this node or attribute.
+ The row and column are 1-based. (That is the first row and first column is
+ 1,1). If the returns values are 0 or less, then the parser does not have
+ a row and column value.
+
+ Generally, the row and column value will be set when the TiXmlDocument::Load(),
+ TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+ when the DOM was created from operator>>.
+
+ The values reflect the initial load. Once the DOM is modified programmatically
+ (by adding or changing nodes and attributes) the new values will NOT update to
+ reflect changes in the document.
+
+ There is a minor performance cost to computing the row and column. Computation
+ can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+ @sa TiXmlDocument::SetTabSize()
+ */
+ int Row() const { return location.row + 1; }
+ int Column() const { return location.col + 1; } ///< See Row()
+
+ void SetUserData( void* user ) { userData = user; }
+ void* GetUserData() { return userData; }
+
+ // Table that returs, for a given lead byte, the total number of bytes
+ // in the UTF-8 sequence.
+ static const int utf8ByteTable[256];
+
+ virtual const char* Parse( const char* p,
+ TiXmlParsingData* data,
+ TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
protected:
- // See STL_STRING_BUG
- // Utility class to overcome a bug.
- class StringToBuffer
- {
- public:
- StringToBuffer( const TIXML_STRING& str );
- ~StringToBuffer();
- char* buffer;
- };
+ // See STL_STRING_BUG
+ // Utility class to overcome a bug.
+ class StringToBuffer
+ {
+ public:
+ StringToBuffer( const TIXML_STRING& str );
+ ~StringToBuffer();
+ char* buffer;
+ };
+
+ static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+ inline static bool IsWhiteSpace( char c )
+ {
+ return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
+ }
- static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
- inline static bool IsWhiteSpace( char c )
- {
- return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
- }
+ virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+
+ #ifdef TIXML_USE_STL
+ static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
+ #endif
+
+ /* Reads an XML name into the string provided. Returns
+ a pointer just past the last character of the name,
+ or 0 if the function has an error.
+ */
+ static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+ /* Reads text. Returns a pointer past the given end tag.
+ Wickedly complex options, but it keeps the (sensitive) code in one place.
+ */
+ static const char* ReadText( const char* in, // where to start
+ TIXML_STRING* text, // the string read
+ bool ignoreWhiteSpace, // whether to keep the white space
+ const char* endTag, // what ends this text
+ bool ignoreCase, // whether to ignore case in the end tag
+ TiXmlEncoding encoding ); // the current encoding
+
+ // If an entity has been found, transform it into a character.
+ static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+ // Get a character, while interpreting entities.
+ // The length can be from 0 to 4 bytes.
+ inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+ {
+ assert( p );
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ *length = utf8ByteTable[ *((unsigned char*)p) ];
+ assert( *length >= 0 && *length < 5 );
+ }
+ else
+ {
+ *length = 1;
+ }
+
+ if ( *length == 1 )
+ {
+ if ( *p == '&' )
+ return GetEntity( p, _value, length, encoding );
+ *_value = *p;
+ return p+1;
+ }
+ else if ( *length )
+ {
+ strncpy( _value, p, *length );
+ return p + (*length);
+ }
+ else
+ {
+ // Not valid text.
+ return 0;
+ }
+ }
- virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+ // Puts a string to a stream, expanding entities as it goes.
+ // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
+ static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
-#ifdef TIXML_USE_STL
+ static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
- static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
- static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
-#endif
+ // Return true if the next characters in the stream are any of the endTag sequences.
+ // Ignore case only works for english, and should only be relied on when comparing
+ // to Engilish words: StringEqual( p, "version", true ) is fine.
+ static bool StringEqual( const char* p,
+ const char* endTag,
+ bool ignoreCase,
+ TiXmlEncoding encoding );
- /* Reads an XML name into the string provided. Returns
- a pointer just past the last character of the name,
- or 0 if the function has an error.
- */
- static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
-
- /* Reads text. Returns a pointer past the given end tag.
- Wickedly complex options, but it keeps the (sensitive) code in one place.
- */
- static const char* ReadText( const char* in, // where to start
- TIXML_STRING* text, // the string read
- bool ignoreWhiteSpace, // whether to keep the white space
- const char* endTag, // what ends this text
- bool ignoreCase, // whether to ignore case in the end tag
- TiXmlEncoding encoding ); // the current encoding
-
- // If an entity has been found, transform it into a character.
- static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
-
- // Get a character, while interpreting entities.
- // The length can be from 0 to 4 bytes.
- inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
- {
- assert( p );
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- *length = utf8ByteTable[ *((unsigned char*)p) ];
- assert( *length >= 0 && *length < 5 );
- }
- else
- {
- *length = 1;
- }
-
- if ( *length == 1 )
- {
- if ( *p == '&' )
- return GetEntity( p, _value, length, encoding );
- *_value = *p;
- return p+1;
- }
- else if ( *length )
- {
- strncpy( _value, p, *length );
- return p + (*length);
- }
- else
- {
- // Not valid text.
- return 0;
- }
- }
-
- // Puts a string to a stream, expanding entities as it goes.
- // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
- static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
-
- static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
-
- // Return true if the next characters in the stream are any of the endTag sequences.
- // Ignore case only works for english, and should only be relied on when comparing
- // to Engilish words: StringEqual( p, "version", true ) is fine.
- static bool StringEqual( const char* p,
- const char* endTag,
- bool ignoreCase,
- TiXmlEncoding encoding );
-
-
- enum
- {
- TIXML_NO_ERROR = 0,
- TIXML_ERROR,
- TIXML_ERROR_OPENING_FILE,
- TIXML_ERROR_OUT_OF_MEMORY,
- TIXML_ERROR_PARSING_ELEMENT,
- TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
- TIXML_ERROR_READING_ELEMENT_VALUE,
- TIXML_ERROR_READING_ATTRIBUTES,
- TIXML_ERROR_PARSING_EMPTY,
- TIXML_ERROR_READING_END_TAG,
- TIXML_ERROR_PARSING_UNKNOWN,
- TIXML_ERROR_PARSING_COMMENT,
- TIXML_ERROR_PARSING_DECLARATION,
- TIXML_ERROR_DOCUMENT_EMPTY,
- TIXML_ERROR_EMBEDDED_NULL,
-
- TIXML_ERROR_STRING_COUNT
- };
- static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
-
- TiXmlCursor location;
-
- /// Field containing a generic user pointer
- void* userData;
-
- // None of these methods are reliable for any language except English.
- // Good for approximation, not great for accuracy.
- static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
- static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
- inline static int ToLower( int v, TiXmlEncoding encoding )
- {
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- if ( v < 128 )
- return tolower( v );
- return v;
- }
- else
- {
- return tolower( v );
- }
- }
- static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+ enum
+ {
+ TIXML_NO_ERROR = 0,
+ TIXML_ERROR,
+ TIXML_ERROR_OPENING_FILE,
+ TIXML_ERROR_OUT_OF_MEMORY,
+ TIXML_ERROR_PARSING_ELEMENT,
+ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+ TIXML_ERROR_READING_ELEMENT_VALUE,
+ TIXML_ERROR_READING_ATTRIBUTES,
+ TIXML_ERROR_PARSING_EMPTY,
+ TIXML_ERROR_READING_END_TAG,
+ TIXML_ERROR_PARSING_UNKNOWN,
+ TIXML_ERROR_PARSING_COMMENT,
+ TIXML_ERROR_PARSING_DECLARATION,
+ TIXML_ERROR_DOCUMENT_EMPTY,
+ TIXML_ERROR_EMBEDDED_NULL,
+
+ TIXML_ERROR_STRING_COUNT
+ };
+ static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+ TiXmlCursor location;
+
+ /// Field containing a generic user pointer
+ void* userData;
+
+ // None of these methods are reliable for any language except English.
+ // Good for approximation, not great for accuracy.
+ static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+ static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+ inline static int ToLower( int v, TiXmlEncoding encoding )
+ {
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ if ( v < 128 ) return tolower( v );
+ return v;
+ }
+ else
+ {
+ return tolower( v );
+ }
+ }
+ static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
private:
- TiXmlBase( const TiXmlBase& ); // not implemented.
- void operator=( const TiXmlBase& base ); // not allowed.
-
- struct Entity
- {
- const char* str;
- unsigned int strLength;
- char chr;
- };
- enum
- {
- NUM_ENTITY = 5,
- MAX_ENTITY_LENGTH = 6
-
- };
- static Entity entity[ NUM_ENTITY ];
- static bool condenseWhiteSpace;
+ TiXmlBase( const TiXmlBase& ); // not implemented.
+ void operator=( const TiXmlBase& base ); // not allowed.
+
+ struct Entity
+ {
+ const char* str;
+ unsigned int strLength;
+ char chr;
+ };
+ enum
+ {
+ NUM_ENTITY = 5,
+ MAX_ENTITY_LENGTH = 6
+
+ };
+ static Entity entity[ NUM_ENTITY ];
+ static bool condenseWhiteSpace;
};
@@ -380,481 +352,383 @@ private:
*/
class TiXmlNode : public TiXmlBase
{
- friend class TiXmlDocument;
- friend class TiXmlElement;
+ friend class TiXmlDocument;
+ friend class TiXmlElement;
public:
-#ifdef TIXML_USE_STL
-
- /** An input stream operator, for every class. Tolerant of newlines and
- formatting, but doesn't expect them.
- */
- friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
-
- /** An output stream operator, for every class. Note that this outputs
- without any newlines or formatting, as opposed to Print(), which
- includes tabs and new lines.
-
- The operator<< and operator>> are not completely symmetric. Writing
- a node to a stream is very well defined. You'll get a nice stream
- of output, without any extra whitespace or newlines.
-
- But reading is not as well defined. (As it always is.) If you create
- a TiXmlElement (for example) and read that from an input stream,
- the text needs to define an element or junk will result. This is
- true of all input streams, but it's worth keeping in mind.
-
- A TiXmlDocument will read nodes until it reads a root element, and
- all the children of that root element.
- */
- friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
-
- /// Appends the XML node or attribute to a std::string.
- friend std::string& operator<< (std::string& out, const TiXmlNode& base );
-
-#else
- // Used internally, not part of the public API.
- friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
-#endif
-
- /** The types of XML nodes supported by TinyXml. (All the
- unsupported types are picked up by UNKNOWN.)
- */
- enum NodeType
- {
- DOCUMENT,
- ELEMENT,
- COMMENT,
- UNKNOWN,
- TEXT,
- DECLARATION,
- TYPECOUNT
- };
-
- virtual ~TiXmlNode();
-
- /** The meaning of 'value' changes for the specific type of
- TiXmlNode.
- @verbatim
- Document: filename of the xml file
- Element: name of the element
- Comment: the comment text
- Unknown: the tag contents
- Text: the text string
- @endverbatim
-
- The subclasses will wrap this function.
- */
- const char * Value() const
- {
- return value.c_str ();
- }
-
- /** Changes the value of the node. Defined as:
- @verbatim
- Document: filename of the xml file
- Element: name of the element
- Comment: the comment text
- Unknown: the tag contents
- Text: the text string
- @endverbatim
- */
- void SetValue(const char * _value)
- {
- value = _value;
- }
-
-#ifdef TIXML_USE_STL
- /// STL std::string form.
- void SetValue( const std::string& _value )
- {
- StringToBuffer buf( _value );
- SetValue( buf.buffer ? buf.buffer : "" );
- }
-#endif
-
- /// Delete all the children of this node. Does not affect 'this'.
- void Clear();
-
- /// One step up the DOM.
- TiXmlNode* Parent() const
- {
- return parent;
- }
-
- TiXmlNode* FirstChild() const
- {
- return firstChild;
- } ///< The first child of this node. Will be null if there are no children.
- TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
-
- TiXmlNode* LastChild() const
- {
- return lastChild;
- } /// The last child of this node. Will be null if there are no children.
- TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
-
-#ifdef TIXML_USE_STL
-
- TiXmlNode* FirstChild( const std::string& _value ) const
- {
- return FirstChild (_value.c_str ());
- } ///< STL std::string form.
- TiXmlNode* LastChild( const std::string& _value ) const
- {
- return LastChild (_value.c_str ());
- } ///< STL std::string form.
-#endif
-
- /** An alternate way to walk the children of a node.
- One way to iterate over nodes is:
- @verbatim
- for( child = parent->FirstChild(); child; child = child->NextSibling() )
- @endverbatim
-
- IterateChildren does the same thing with the syntax:
- @verbatim
- child = 0;
- while( child = parent->IterateChildren( child ) )
- @endverbatim
-
- IterateChildren takes the previous child as input and finds
- the next one. If the previous child is null, it returns the
- first. IterateChildren will return null when done.
- */
- TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
-
- /// This flavor of IterateChildren searches for children with a particular 'value'
- TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
-
-#ifdef TIXML_USE_STL
-
- TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const
- {
- return IterateChildren (_value.c_str (), previous);
- } ///< STL std::string form.
-#endif
-
- /** Add a new node related to this. Adds a child past the LastChild.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
-
-
- /** Add a new node related to this. Adds a child past the LastChild.
-
- NOTE: the node to be added is passed by pointer, and will be
- henceforth owned (and deleted) by tinyXml. This method is efficient
- and avoids an extra copy, but should be used with care as it
- uses a different memory model than the other insert functions.
-
- @sa InsertEndChild
- */
- TiXmlNode* LinkEndChild( TiXmlNode* addThis );
-
- /** Add a new node related to this. Adds a child before the specified child.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
-
- /** Add a new node related to this. Adds a child after the specified child.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
-
- /** Replace a child of this node.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
-
- /// Delete a child of this node.
- bool RemoveChild( TiXmlNode* removeThis );
-
- /// Navigate to a sibling node.
- TiXmlNode* PreviousSibling() const
- {
- return prev;
- }
-
- /// Navigate to a sibling node.
- TiXmlNode* PreviousSibling( const char * ) const;
-
-#ifdef TIXML_USE_STL
-
- TiXmlNode* PreviousSibling( const std::string& _value ) const
- {
- return PreviousSibling (_value.c_str ());
- } ///< STL std::string form.
- TiXmlNode* NextSibling( const std::string& _value) const
- {
- return NextSibling (_value.c_str ());
- } ///< STL std::string form.
-#endif
-
- /// Navigate to a sibling node.
- TiXmlNode* NextSibling() const
- {
- return next;
- }
-
- /// Navigate to a sibling node with the given 'value'.
- TiXmlNode* NextSibling( const char * ) const;
-
- /** Convenience function to get through elements.
- Calls NextSibling and ToElement. Will skip all non-Element
- nodes. Returns 0 if there is not another element.
- */
- TiXmlElement* NextSiblingElement() const;
-
- /** Convenience function to get through elements.
- Calls NextSibling and ToElement. Will skip all non-Element
- nodes. Returns 0 if there is not another element.
- */
- TiXmlElement* NextSiblingElement( const char * ) const;
-
-#ifdef TIXML_USE_STL
-
- TiXmlElement* NextSiblingElement( const std::string& _value) const
- {
- return NextSiblingElement (_value.c_str ());
- } ///< STL std::string form.
-#endif
-
- /// Convenience function to get through elements.
- TiXmlElement* FirstChildElement() const;
-
- /// Convenience function to get through elements.
- TiXmlElement* FirstChildElement( const char * value ) const;
+ #ifdef TIXML_USE_STL
+
+ /** An input stream operator, for every class. Tolerant of newlines and
+ formatting, but doesn't expect them.
+ */
+ friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+ /** An output stream operator, for every class. Note that this outputs
+ without any newlines or formatting, as opposed to Print(), which
+ includes tabs and new lines.
+
+ The operator<< and operator>> are not completely symmetric. Writing
+ a node to a stream is very well defined. You'll get a nice stream
+ of output, without any extra whitespace or newlines.
+
+ But reading is not as well defined. (As it always is.) If you create
+ a TiXmlElement (for example) and read that from an input stream,
+ the text needs to define an element or junk will result. This is
+ true of all input streams, but it's worth keeping in mind.
+
+ A TiXmlDocument will read nodes until it reads a root element, and
+ all the children of that root element.
+ */
+ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+ /// Appends the XML node or attribute to a std::string.
+ friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+ #else
+ // Used internally, not part of the public API.
+ friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
+ #endif
+
+ /** The types of XML nodes supported by TinyXml. (All the
+ unsupported types are picked up by UNKNOWN.)
+ */
+ enum NodeType
+ {
+ DOCUMENT,
+ ELEMENT,
+ COMMENT,
+ UNKNOWN,
+ TEXT,
+ DECLARATION,
+ TYPECOUNT
+ };
+
+ virtual ~TiXmlNode();
+
+ /** The meaning of 'value' changes for the specific type of
+ TiXmlNode.
+ @verbatim
+ Document: filename of the xml file
+ Element: name of the element
+ Comment: the comment text
+ Unknown: the tag contents
+ Text: the text string
+ @endverbatim
+
+ The subclasses will wrap this function.
+ */
+ const char * Value() const { return value.c_str (); }
+
+ /** Changes the value of the node. Defined as:
+ @verbatim
+ Document: filename of the xml file
+ Element: name of the element
+ Comment: the comment text
+ Unknown: the tag contents
+ Text: the text string
+ @endverbatim
+ */
+ void SetValue(const char * _value) { value = _value;}
+
+ #ifdef TIXML_USE_STL
+ /// STL std::string form.
+ void SetValue( const std::string& _value )
+ {
+ StringToBuffer buf( _value );
+ SetValue( buf.buffer ? buf.buffer : "" );
+ }
+ #endif
+
+ /// Delete all the children of this node. Does not affect 'this'.
+ void Clear();
+
+ /// One step up the DOM.
+ TiXmlNode* Parent() const { return parent; }
+
+ TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
+ TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
+
+ TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
+ TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
+
+ #ifdef TIXML_USE_STL
+ TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form.
+ #endif
+
+ /** An alternate way to walk the children of a node.
+ One way to iterate over nodes is:
+ @verbatim
+ for( child = parent->FirstChild(); child; child = child->NextSibling() )
+ @endverbatim
+
+ IterateChildren does the same thing with the syntax:
+ @verbatim
+ child = 0;
+ while( child = parent->IterateChildren( child ) )
+ @endverbatim
+
+ IterateChildren takes the previous child as input and finds
+ the next one. If the previous child is null, it returns the
+ first. IterateChildren will return null when done.
+ */
+ TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
+
+ /// This flavor of IterateChildren searches for children with a particular 'value'
+ TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
+
+ #ifdef TIXML_USE_STL
+ TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
+ #endif
+
+ /** Add a new node related to this. Adds a child past the LastChild.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+ /** Add a new node related to this. Adds a child past the LastChild.
+
+ NOTE: the node to be added is passed by pointer, and will be
+ henceforth owned (and deleted) by tinyXml. This method is efficient
+ and avoids an extra copy, but should be used with care as it
+ uses a different memory model than the other insert functions.
+
+ @sa InsertEndChild
+ */
+ TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+ /** Add a new node related to this. Adds a child before the specified child.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+ /** Add a new node related to this. Adds a child after the specified child.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+ /** Replace a child of this node.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+ /// Delete a child of this node.
+ bool RemoveChild( TiXmlNode* removeThis );
+
+ /// Navigate to a sibling node.
+ TiXmlNode* PreviousSibling() const { return prev; }
+
+ /// Navigate to a sibling node.
+ TiXmlNode* PreviousSibling( const char * ) const;
+
+ #ifdef TIXML_USE_STL
+ TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form.
+ #endif
+
+ /// Navigate to a sibling node.
+ TiXmlNode* NextSibling() const { return next; }
+
+ /// Navigate to a sibling node with the given 'value'.
+ TiXmlNode* NextSibling( const char * ) const;
+
+ /** Convenience function to get through elements.
+ Calls NextSibling and ToElement. Will skip all non-Element
+ nodes. Returns 0 if there is not another element.
+ */
+ TiXmlElement* NextSiblingElement() const;
-#ifdef TIXML_USE_STL
+ /** Convenience function to get through elements.
+ Calls NextSibling and ToElement. Will skip all non-Element
+ nodes. Returns 0 if there is not another element.
+ */
+ TiXmlElement* NextSiblingElement( const char * ) const;
+
+ #ifdef TIXML_USE_STL
+ TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
+ #endif
+
+ /// Convenience function to get through elements.
+ TiXmlElement* FirstChildElement() const;
+
+ /// Convenience function to get through elements.
+ TiXmlElement* FirstChildElement( const char * value ) const;
+
+ #ifdef TIXML_USE_STL
+ TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
+ #endif
+
+ /** Query the type (as an enumerated value, above) of this node.
+ The possible types are: DOCUMENT, ELEMENT, COMMENT,
+ UNKNOWN, TEXT, and DECLARATION.
+ */
+ virtual int Type() const { return type; }
+
+ /** Return a pointer to the Document this node lives in.
+ Returns null if not in a document.
+ */
+ TiXmlDocument* GetDocument() const;
+
+ /// Returns true if this node has no children.
+ bool NoChildren() const { return !firstChild; }
- TiXmlElement* FirstChildElement( const std::string& _value ) const
- {
- return FirstChildElement (_value.c_str ());
- } ///< STL std::string form.
-#endif
+ TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- /** Query the type (as an enumerated value, above) of this node.
- The possible types are: DOCUMENT, ELEMENT, COMMENT,
- UNKNOWN, TEXT, and DECLARATION.
- */
- virtual int Type() const
- {
- return type;
- }
-
- /** Return a pointer to the Document this node lives in.
- Returns null if not in a document.
- */
- TiXmlDocument* GetDocument() const;
-
- /// Returns true if this node has no children.
- bool NoChildren() const
- {
- return !firstChild;
- }
-
- TiXmlDocument* ToDocument() const
- {
- return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlElement* ToElement() const
- {
- return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlComment* ToComment() const
- {
- return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlUnknown* ToUnknown() const
- {
- return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlText* ToText() const
- {
- return ( this && type == TEXT ) ? (TiXmlText*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlDeclaration* ToDeclaration() const
- {
- return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0;
- } ///< Cast to a more defined type. Will return null not of the requested type.
-
- /** Create an exact duplicate of this node and return it. The memory must be deleted
- by the caller.
- */
- virtual TiXmlNode* Clone() const = 0;
+ /** Create an exact duplicate of this node and return it. The memory must be deleted
+ by the caller.
+ */
+ virtual TiXmlNode* Clone() const = 0;
protected:
- TiXmlNode( NodeType _type );
+ TiXmlNode( NodeType _type );
- // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
- // and the assignment operator.
- void CopyTo( TiXmlNode* target ) const;
+ // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+ // and the assignment operator.
+ void CopyTo( TiXmlNode* target ) const;
-#ifdef TIXML_USE_STL
- // The real work of the input operator.
- virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
-#endif
+ #ifdef TIXML_USE_STL
+ // The real work of the input operator.
+ virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
+ #endif
- // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
- TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+ // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+ TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
- // Internal Value function returning a TIXML_STRING
- const TIXML_STRING& SValue() const
- {
- return value ;
- }
+ // Internal Value function returning a TIXML_STRING
+ const TIXML_STRING& SValue() const { return value ; }
- TiXmlNode* parent;
- NodeType type;
+ TiXmlNode* parent;
+ NodeType type;
- TiXmlNode* firstChild;
- TiXmlNode* lastChild;
+ TiXmlNode* firstChild;
+ TiXmlNode* lastChild;
- TIXML_STRING value;
+ TIXML_STRING value;
- TiXmlNode* prev;
- TiXmlNode* next;
+ TiXmlNode* prev;
+ TiXmlNode* next;
private:
- TiXmlNode( const TiXmlNode& ); // not implemented.
- void operator=( const TiXmlNode& base ); // not allowed.
+ TiXmlNode( const TiXmlNode& ); // not implemented.
+ void operator=( const TiXmlNode& base ); // not allowed.
};
/** An attribute is a name-value pair. Elements have an arbitrary
number of attributes, each with a unique name.
-
+
@note The attributes are not TiXmlNodes, since they are not
part of the tinyXML document object model. There are other
suggested ways to look at this problem.
*/
class TiXmlAttribute : public TiXmlBase
{
- friend class TiXmlAttributeSet;
+ friend class TiXmlAttributeSet;
public:
- /// Construct an empty attribute.
- TiXmlAttribute() : TiXmlBase()
- {
- document = 0;
- prev = next = 0;
- }
+ /// Construct an empty attribute.
+ TiXmlAttribute() : TiXmlBase()
+ {
+ document = 0;
+ prev = next = 0;
+ }
-#ifdef TIXML_USE_STL
- /// std::string constructor.
- TiXmlAttribute( const std::string& _name, const std::string& _value )
- {
- name = _name;
- value = _value;
- document = 0;
- prev = next = 0;
- }
-#endif
+ #ifdef TIXML_USE_STL
+ /// std::string constructor.
+ TiXmlAttribute( const std::string& _name, const std::string& _value )
+ {
+ name = _name;
+ value = _value;
+ document = 0;
+ prev = next = 0;
+ }
+ #endif
- /// Construct an attribute with a name and value.
- TiXmlAttribute( const char * _name, const char * _value )
- {
- name = _name;
- value = _value;
- document = 0;
- prev = next = 0;
- }
-
- const char* Name() const
- {
- return name.c_str ();
- } ///< Return the name of this attribute.
- const char* Value() const
- {
- return value.c_str ();
- } ///< Return the value of this attribute.
- const int IntValue() const; ///< Return the value of this attribute, converted to an integer.
- const double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
-
- /** QueryIntValue examines the value string. It is an alternative to the
- IntValue() method with richer error checking.
- If the value is an integer, it is stored in 'value' and
- the call returns TIXML_SUCCESS. If it is not
- an integer, it returns TIXML_WRONG_TYPE.
-
- A specialized but useful call. Note that for success it returns 0,
- which is the opposite of almost all other TinyXml calls.
- */
- int QueryIntValue( int* value ) const;
- /// QueryDoubleValue examines the value string. See QueryIntValue().
- int QueryDoubleValue( double* value ) const;
-
- void SetName( const char* _name )
- {
- name = _name;
- } ///< Set the name of this attribute.
- void SetValue( const char* _value )
- {
- value = _value;
- } ///< Set the value.
-
- void SetIntValue( int value ); ///< Set the value from an integer.
- void SetDoubleValue( double value ); ///< Set the value from a double.
+ /// Construct an attribute with a name and value.
+ TiXmlAttribute( const char * _name, const char * _value )
+ {
+ name = _name;
+ value = _value;
+ document = 0;
+ prev = next = 0;
+ }
-#ifdef TIXML_USE_STL
- /// STL std::string form.
- void SetName( const std::string& _name )
- {
- StringToBuffer buf( _name );
- SetName ( buf.buffer ? buf.buffer : "error" );
- }
- /// STL std::string form.
- void SetValue( const std::string& _value )
- {
- StringToBuffer buf( _value );
- SetValue( buf.buffer ? buf.buffer : "error" );
- }
-#endif
+ const char* Name() const { return name.c_str (); } ///< Return the name of this attribute.
+ const char* Value() const { return value.c_str (); } ///< Return the value of this attribute.
+ const int IntValue() const; ///< Return the value of this attribute, converted to an integer.
+ const double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
+
+ /** QueryIntValue examines the value string. It is an alternative to the
+ IntValue() method with richer error checking.
+ If the value is an integer, it is stored in 'value' and
+ the call returns TIXML_SUCCESS. If it is not
+ an integer, it returns TIXML_WRONG_TYPE.
+
+ A specialized but useful call. Note that for success it returns 0,
+ which is the opposite of almost all other TinyXml calls.
+ */
+ int QueryIntValue( int* value ) const;
+ /// QueryDoubleValue examines the value string. See QueryIntValue().
+ int QueryDoubleValue( double* value ) const;
+
+ void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute.
+ void SetValue( const char* _value ) { value = _value; } ///< Set the value.
+
+ void SetIntValue( int value ); ///< Set the value from an integer.
+ void SetDoubleValue( double value ); ///< Set the value from a double.
+
+ #ifdef TIXML_USE_STL
+ /// STL std::string form.
+ void SetName( const std::string& _name )
+ {
+ StringToBuffer buf( _name );
+ SetName ( buf.buffer ? buf.buffer : "error" );
+ }
+ /// STL std::string form.
+ void SetValue( const std::string& _value )
+ {
+ StringToBuffer buf( _value );
+ SetValue( buf.buffer ? buf.buffer : "error" );
+ }
+ #endif
+
+ /// Get the next sibling attribute in the DOM. Returns null at end.
+ TiXmlAttribute* Next() const;
+ /// Get the previous sibling attribute in the DOM. Returns null at beginning.
+ TiXmlAttribute* Previous() const;
+
+ bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+ bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
+ bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
- /// Get the next sibling attribute in the DOM. Returns null at end.
- TiXmlAttribute* Next() const;
- /// Get the previous sibling attribute in the DOM. Returns null at beginning.
- TiXmlAttribute* Previous() const;
-
- bool operator==( const TiXmlAttribute& rhs ) const
- {
- return rhs.name == name;
- }
- bool operator<( const TiXmlAttribute& rhs ) const
- {
- return name < rhs.name;
- }
- bool operator>( const TiXmlAttribute& rhs ) const
- {
- return name > rhs.name;
- }
-
- /* Attribute parsing starts: first letter of the name
- returns: the next char after the value end quote
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
- // Prints this Attribute to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
- // [internal use]
- // Set the document pointer so the attribute can report errors.
- void SetDocument( TiXmlDocument* doc )
- {
- document = doc;
- }
+ /* Attribute parsing starts: first letter of the name
+ returns: the next char after the value end quote
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+ // Prints this Attribute to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
+
+ virtual void StreamOut( TIXML_OSTREAM * out ) const;
+ // [internal use]
+ // Set the document pointer so the attribute can report errors.
+ void SetDocument( TiXmlDocument* doc ) { document = doc; }
private:
- TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
- void operator=( const TiXmlAttribute& base ); // not allowed.
-
- TiXmlDocument* document; // A pointer back to a document, for error reporting.
- TIXML_STRING name;
- TIXML_STRING value;
- TiXmlAttribute* prev;
- TiXmlAttribute* next;
+ TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
+ void operator=( const TiXmlAttribute& base ); // not allowed.
+
+ TiXmlDocument* document; // A pointer back to a document, for error reporting.
+ TIXML_STRING name;
+ TIXML_STRING value;
+ TiXmlAttribute* prev;
+ TiXmlAttribute* next;
};
@@ -865,7 +739,7 @@ private:
classes that use it, but NOT transparent to the Attribute
which has to implement a next() and previous() method. Which makes
it a bit problematic and prevents the use of STL.
-
+
This version is implemented with circular lists because:
- I like circular lists
- it demonstrates some independence from the (typical) doubly linked list.
@@ -873,24 +747,18 @@ private:
class TiXmlAttributeSet
{
public:
- TiXmlAttributeSet();
- ~TiXmlAttributeSet();
-
- void Add( TiXmlAttribute* attribute );
- void Remove( TiXmlAttribute* attribute );
-
- TiXmlAttribute* First() const
- {
- return ( sentinel.next == &sentinel ) ? 0 : sentinel.next;
- }
- TiXmlAttribute* Last() const
- {
- return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev;
- }
- TiXmlAttribute* Find( const char * name ) const;
+ TiXmlAttributeSet();
+ ~TiXmlAttributeSet();
+
+ void Add( TiXmlAttribute* attribute );
+ void Remove( TiXmlAttribute* attribute );
+
+ TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+ TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+ TiXmlAttribute* Find( const char * name ) const;
private:
- TiXmlAttribute sentinel;
+ TiXmlAttribute sentinel;
};
@@ -901,159 +769,131 @@ private:
class TiXmlElement : public TiXmlNode
{
public:
- /// Construct an element.
- TiXmlElement (const char * in_value);
-
-#ifdef TIXML_USE_STL
- /// std::string constructor.
- TiXmlElement( const std::string& _value );
-#endif
-
- TiXmlElement( const TiXmlElement& );
-
- void operator=( const TiXmlElement& base );
-
- virtual ~TiXmlElement();
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- */
- const char* Attribute( const char* name ) const;
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- If the attribute exists and can be converted to an integer,
- the integer value will be put in the return 'i', if 'i'
- is non-null.
- */
- const char* Attribute( const char* name, int* i ) const;
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- If the attribute exists and can be converted to an double,
- the double value will be put in the return 'd', if 'd'
- is non-null.
- */
- const char* Attribute( const char* name, double* d ) const;
-
- /** QueryIntAttribute examines the attribute - it is an alternative to the
- Attribute() method with richer error checking.
- If the attribute is an integer, it is stored in 'value' and
- the call returns TIXML_SUCCESS. If it is not
- an integer, it returns TIXML_WRONG_TYPE. If the attribute
- does not exist, then TIXML_NO_ATTRIBUTE is returned.
- */
- int QueryIntAttribute( const char* name, int* value ) const;
- /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
- int QueryDoubleAttribute( const char* name, double* value ) const;
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetAttribute( const char* name, const char * value );
-
-#ifdef TIXML_USE_STL
-
- const char* Attribute( const std::string& name ) const
- {
- return Attribute( name.c_str() );
- }
- const char* Attribute( const std::string& name, int* i ) const
- {
- return Attribute( name.c_str(), i );
- }
- const char* Attribute( const std::string& name, double* d ) const
- {
- return Attribute( name.c_str(), d );
- }
- int QueryIntAttribute( const std::string& name, int* value ) const
- {
- return QueryIntAttribute( name.c_str(), value );
- }
- int QueryDoubleAttribute( const std::string& name, double* value ) const
- {
- return QueryDoubleAttribute( name.c_str(), value );
- }
-
- /// STL std::string form.
- void SetAttribute( const std::string& name, const std::string& _value )
- {
- StringToBuffer n( name );
- StringToBuffer v( _value );
- if ( n.buffer && v.buffer )
- SetAttribute (n.buffer, v.buffer );
- }
- ///< STL std::string form.
- void SetAttribute( const std::string& name, int _value )
- {
- StringToBuffer n( name );
- if ( n.buffer )
- SetAttribute (n.buffer, _value);
- }
-#endif
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetAttribute( const char * name, int value );
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetDoubleAttribute( const char * name, double value );
-
- /** Deletes an attribute with the given name.
- */
- void RemoveAttribute( const char * name );
-#ifdef TIXML_USE_STL
-
- void RemoveAttribute( const std::string& name )
- {
- RemoveAttribute (name.c_str ());
- } ///< STL std::string form.
-#endif
-
- TiXmlAttribute* FirstAttribute() const
- {
- return attributeSet.First();
- } ///< Access the first attribute in this element.
- TiXmlAttribute* LastAttribute() const
- {
- return attributeSet.Last();
- } ///< Access the last attribute in this element.
-
- /// Creates a new Element and returns it - the returned element is a copy.
- virtual TiXmlNode* Clone() const;
- // Print the Element to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- /* Attribtue parsing starts: next char past '<'
- returns: next char past '>'
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ /// Construct an element.
+ TiXmlElement (const char * in_value);
+
+ #ifdef TIXML_USE_STL
+ /// std::string constructor.
+ TiXmlElement( const std::string& _value );
+ #endif
+
+ TiXmlElement( const TiXmlElement& );
+
+ void operator=( const TiXmlElement& base );
+
+ virtual ~TiXmlElement();
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ */
+ const char* Attribute( const char* name ) const;
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ If the attribute exists and can be converted to an integer,
+ the integer value will be put in the return 'i', if 'i'
+ is non-null.
+ */
+ const char* Attribute( const char* name, int* i ) const;
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ If the attribute exists and can be converted to an double,
+ the double value will be put in the return 'd', if 'd'
+ is non-null.
+ */
+ const char* Attribute( const char* name, double* d ) const;
+
+ /** QueryIntAttribute examines the attribute - it is an alternative to the
+ Attribute() method with richer error checking.
+ If the attribute is an integer, it is stored in 'value' and
+ the call returns TIXML_SUCCESS. If it is not
+ an integer, it returns TIXML_WRONG_TYPE. If the attribute
+ does not exist, then TIXML_NO_ATTRIBUTE is returned.
+ */
+ int QueryIntAttribute( const char* name, int* value ) const;
+ /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+ int QueryDoubleAttribute( const char* name, double* value ) const;
+
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetAttribute( const char* name, const char * value );
+
+ #ifdef TIXML_USE_STL
+ const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }
+ const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }
+ const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); }
+ int QueryIntAttribute( const std::string& name, int* value ) const { return QueryIntAttribute( name.c_str(), value ); }
+ int QueryDoubleAttribute( const std::string& name, double* value ) const { return QueryDoubleAttribute( name.c_str(), value ); }
+
+ /// STL std::string form.
+ void SetAttribute( const std::string& name, const std::string& _value )
+ {
+ StringToBuffer n( name );
+ StringToBuffer v( _value );
+ if ( n.buffer && v.buffer )
+ SetAttribute (n.buffer, v.buffer );
+ }
+ ///< STL std::string form.
+ void SetAttribute( const std::string& name, int _value )
+ {
+ StringToBuffer n( name );
+ if ( n.buffer )
+ SetAttribute (n.buffer, _value);
+ }
+ #endif
+
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetAttribute( const char * name, int value );
+
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetDoubleAttribute( const char * name, double value );
+
+ /** Deletes an attribute with the given name.
+ */
+ void RemoveAttribute( const char * name );
+ #ifdef TIXML_USE_STL
+ void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
+ #endif
+
+ TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
+ TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element.
+
+ /// Creates a new Element and returns it - the returned element is a copy.
+ virtual TiXmlNode* Clone() const;
+ // Print the Element to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
+
+ /* Attribtue parsing starts: next char past '<'
+ returns: next char past '>'
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
protected:
- void CopyTo( TiXmlElement* target ) const;
- void ClearThis(); // like clear, but initializes 'this' object as well
-
- // Used to be public [internal use]
-#ifdef TIXML_USE_STL
-
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ void CopyTo( TiXmlElement* target ) const;
+ void ClearThis(); // like clear, but initializes 'this' object as well
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
+ // Used to be public [internal use]
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
+ virtual void StreamOut( TIXML_OSTREAM * out ) const;
- /* [internal use]
- Reads the "value" of the element -- another element, or text.
- This should terminate with the current end tag.
- */
- const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+ /* [internal use]
+ Reads the "value" of the element -- another element, or text.
+ This should terminate with the current end tag.
+ */
+ const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
private:
- TiXmlAttributeSet attributeSet;
+ TiXmlAttributeSet attributeSet;
};
@@ -1062,35 +902,31 @@ private:
class TiXmlComment : public TiXmlNode
{
public:
- /// Constructs an empty comment.
- TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT )
- {}
- TiXmlComment( const TiXmlComment& );
- void operator=( const TiXmlComment& base );
+ /// Constructs an empty comment.
+ TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+ TiXmlComment( const TiXmlComment& );
+ void operator=( const TiXmlComment& base );
- virtual ~TiXmlComment()
- {}
+ virtual ~TiXmlComment() {}
- /// Returns a copy of this Comment.
- virtual TiXmlNode* Clone() const;
- /// Write this Comment to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ /// Returns a copy of this Comment.
+ virtual TiXmlNode* Clone() const;
+ /// Write this Comment to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
- /* Attribtue parsing starts: at the ! of the !--
- returns: next char past '>'
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ /* Attribtue parsing starts: at the ! of the !--
+ returns: next char past '>'
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
protected:
- void CopyTo( TiXmlComment* target ) const;
-
- // used to be public
-#ifdef TIXML_USE_STL
-
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ void CopyTo( TiXmlComment* target ) const;
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
+ // used to be public
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
+ virtual void StreamOut( TIXML_OSTREAM * out ) const;
private:
@@ -1101,50 +937,42 @@ private:
*/
class TiXmlText : public TiXmlNode
{
- friend class TiXmlElement;
+ friend class TiXmlElement;
public:
- /// Constructor.
- TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
- {
- SetValue( initValue );
- }
- virtual ~TiXmlText()
- {}
+ /// Constructor.
+ TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
+ {
+ SetValue( initValue );
+ }
+ virtual ~TiXmlText() {}
-#ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
- {
- SetValue( initValue );
- }
-#endif
+ #ifdef TIXML_USE_STL
+ /// Constructor.
+ TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+ {
+ SetValue( initValue );
+ }
+ #endif
- TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )
- {
- copy.CopyTo( this );
- }
- void operator=( const TiXmlText& base )
- {
- base.CopyTo( this );
- }
+ TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); }
+ void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
- /// Write this text object to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ /// Write this text object to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
protected :
- /// [internal use] Creates a new Element and returns it.
- virtual TiXmlNode* Clone() const;
- void CopyTo( TiXmlText* target ) const;
-
- virtual void StreamOut ( TIXML_OSTREAM * out ) const;
- bool Blank() const; // returns true if all white space and new lines
- // [internal use]
-#ifdef TIXML_USE_STL
+ /// [internal use] Creates a new Element and returns it.
+ virtual TiXmlNode* Clone() const;
+ void CopyTo( TiXmlText* target ) const;
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+ bool Blank() const; // returns true if all white space and new lines
+ // [internal use]
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
private:
};
@@ -1154,11 +982,11 @@ private:
@verbatim
<?xml version="1.0" standalone="yes"?>
@endverbatim
-
+
TinyXml will happily read or write files without a declaration,
however. There are 3 possible attributes to the declaration:
version, encoding, and standalone.
-
+
Note: In this version of the code, the attributes are
handled as special cases, not generic attributes, simply
because there can only be at most 3 and they are always the same.
@@ -1166,66 +994,53 @@ private:
class TiXmlDeclaration : public TiXmlNode
{
public:
- /// Construct an empty declaration.
- TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION )
- {}
+ /// Construct an empty declaration.
+ TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
#ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlDeclaration( const std::string& _version,
- const std::string& _encoding,
- const std::string& _standalone );
+ /// Constructor.
+ TiXmlDeclaration( const std::string& _version,
+ const std::string& _encoding,
+ const std::string& _standalone );
#endif
- /// Construct.
- TiXmlDeclaration( const char* _version,
- const char* _encoding,
- const char* _standalone );
-
- TiXmlDeclaration( const TiXmlDeclaration& copy );
- void operator=( const TiXmlDeclaration& copy );
-
- virtual ~TiXmlDeclaration()
- {}
-
- /// Version. Will return an empty string if none was found.
- const char *Version() const
- {
- return version.c_str ();
- }
- /// Encoding. Will return an empty string if none was found.
- const char *Encoding() const
- {
- return encoding.c_str ();
- }
- /// Is this a standalone document?
- const char *Standalone() const
- {
- return standalone.c_str ();
- }
-
- /// Creates a copy of this Declaration and returns it.
- virtual TiXmlNode* Clone() const;
- /// Print this declaration to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ /// Construct.
+ TiXmlDeclaration( const char* _version,
+ const char* _encoding,
+ const char* _standalone );
-protected:
- void CopyTo( TiXmlDeclaration* target ) const;
- // used to be public
-#ifdef TIXML_USE_STL
+ TiXmlDeclaration( const TiXmlDeclaration& copy );
+ void operator=( const TiXmlDeclaration& copy );
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ virtual ~TiXmlDeclaration() {}
+
+ /// Version. Will return an empty string if none was found.
+ const char *Version() const { return version.c_str (); }
+ /// Encoding. Will return an empty string if none was found.
+ const char *Encoding() const { return encoding.c_str (); }
+ /// Is this a standalone document?
+ const char *Standalone() const { return standalone.c_str (); }
+
+ /// Creates a copy of this Declaration and returns it.
+ virtual TiXmlNode* Clone() const;
+ /// Print this declaration to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
+
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
- virtual void StreamOut ( TIXML_OSTREAM * out) const;
+protected:
+ void CopyTo( TiXmlDeclaration* target ) const;
+ // used to be public
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
+ virtual void StreamOut ( TIXML_OSTREAM * out) const;
private:
- TIXML_STRING version;
- TIXML_STRING encoding;
- TIXML_STRING standalone;
+ TIXML_STRING version;
+ TIXML_STRING encoding;
+ TIXML_STRING standalone;
};
@@ -1233,42 +1048,32 @@ private:
unknown. It is a tag of text, but should not be modified.
It will be written back to the XML, unchanged, when the file
is saved.
-
+
DTD tags get thrown into TiXmlUnknowns.
*/
class TiXmlUnknown : public TiXmlNode
{
public:
- TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )
- {}
- virtual ~TiXmlUnknown()
- {}
-
- TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )
- {
- copy.CopyTo( this );
- }
- void operator=( const TiXmlUnknown& copy )
- {
- copy.CopyTo( this );
- }
-
- /// Creates a copy of this Unknown and returns it.
- virtual TiXmlNode* Clone() const;
- /// Print this Unknown to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
+ virtual ~TiXmlUnknown() {}
-protected:
- void CopyTo( TiXmlUnknown* target ) const;
+ TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); }
+ void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
-#ifdef TIXML_USE_STL
+ /// Creates a copy of this Unknown and returns it.
+ virtual TiXmlNode* Clone() const;
+ /// Print this Unknown to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+ void CopyTo( TiXmlUnknown* target ) const;
- virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
+ virtual void StreamOut ( TIXML_OSTREAM * out ) const;
private:
@@ -1282,173 +1087,141 @@ private:
class TiXmlDocument : public TiXmlNode
{
public:
- /// Create an empty document, that has no name.
- TiXmlDocument();
- /// Create a document with a name. The name of the document is also the filename of the xml.
- TiXmlDocument( const char * documentName );
-
-#ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlDocument( const std::string& documentName );
-#endif
-
- TiXmlDocument( const TiXmlDocument& copy );
- void operator=( const TiXmlDocument& copy );
-
- virtual ~TiXmlDocument()
- {}
-
- /** Load a file using the current document value.
- Returns true if successful. Will delete any existing
- document data before loading.
- */
- bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
- /// Save a file using the current document value. Returns true if successful.
- bool SaveFile() const;
- /// Load a file using the given filename. Returns true if successful.
- bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
- /// Save a file using the given filename. Returns true if successful.
- bool SaveFile( const char * filename ) const;
-
-#ifdef TIXML_USE_STL
-
- bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
- {
- StringToBuffer f( filename );
- return ( f.buffer && LoadFile( f.buffer, encoding ));
- }
- bool SaveFile( const std::string& filename ) const ///< STL std::string version.
- {
- StringToBuffer f( filename );
- return ( f.buffer && SaveFile( f.buffer ));
- }
-#endif
-
- /** Parse the given null terminated block of xml data. Passing in an encoding to this
- method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
- to use that encoding, regardless of what TinyXml might otherwise try to detect.
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-
- /** Get the root element -- the only top level element -- of the document.
- In well formed XML, there should only be one. TinyXml is tolerant of
- multiple elements at the document level.
- */
- TiXmlElement* RootElement() const
- {
- return FirstChildElement();
- }
-
- /** If an error occurs, Error will be set to true. Also,
- - The ErrorId() will contain the integer identifier of the error (not generally useful)
- - The ErrorDesc() method will return the name of the error. (very useful)
- - The ErrorRow() and ErrorCol() will return the location of the error (if known)
- */
- bool Error() const
- {
- return error;
- }
-
- /// Contains a textual (english) description of the error if one occurs.
- const char * ErrorDesc() const
- {
- return errorDesc.c_str ();
- }
-
- /** Generally, you probably want the error string ( ErrorDesc() ). But if you
- prefer the ErrorId, this function will fetch it.
- */
- const int ErrorId() const
- {
- return errorId;
- }
-
- /** Returns the location (if known) of the error. The first column is column 1,
- and the first row is row 1. A value of 0 means the row and column wasn't applicable
- (memory errors, for example, have no row/column) or the parser lost the error. (An
- error in the error reporting, in that case.)
-
- @sa SetTabSize, Row, Column
- */
- int ErrorRow()
- {
- return errorLocation.row+1;
- }
- int ErrorCol()
- {
- return errorLocation.col+1;
- } ///< The column where the error occured. See ErrorRow()
-
- /** By calling this method, with a tab size
- greater than 0, the row and column of each node and attribute is stored
- when the file is loaded. Very useful for tracking the DOM back in to
- the source file.
-
- The tab size is required for calculating the location of nodes. If not
- set, the default of 4 is used. The tabsize is set per document. Setting
- the tabsize to 0 disables row/column tracking.
-
- Note that row and column tracking is not supported when using operator>>.
-
- The tab size needs to be enabled before the parse or load. Correct usage:
- @verbatim
- TiXmlDocument doc;
- doc.SetTabSize( 8 );
- doc.Load( "myfile.xml" );
- @endverbatim
-
- @sa Row, Column
- */
- void SetTabSize( int _tabsize )
- {
- tabsize = _tabsize;
- }
-
- int TabSize() const
- {
- return tabsize;
- }
-
- /** If you have handled the error, it can be reset with this call. The error
- state is automatically cleared if you Parse a new XML block.
- */
- void ClearError()
- {
- error = false;
- errorId = 0;
- errorDesc = "";
- errorLocation.row = errorLocation.col = 0;
- //errorLocation.last = 0;
- }
-
- /** Dump the document to standard out. */
- void Print() const
- {
- Print( stdout, 0 );
- }
-
- /// Print this Document to a FILE stream.
- virtual void Print( FILE* cfile, int depth = 0 ) const;
- // [internal use]
- void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+ /// Create an empty document, that has no name.
+ TiXmlDocument();
+ /// Create a document with a name. The name of the document is also the filename of the xml.
+ TiXmlDocument( const char * documentName );
+
+ #ifdef TIXML_USE_STL
+ /// Constructor.
+ TiXmlDocument( const std::string& documentName );
+ #endif
+
+ TiXmlDocument( const TiXmlDocument& copy );
+ void operator=( const TiXmlDocument& copy );
+
+ virtual ~TiXmlDocument() {}
+
+ /** Load a file using the current document value.
+ Returns true if successful. Will delete any existing
+ document data before loading.
+ */
+ bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the current document value. Returns true if successful.
+ bool SaveFile() const;
+ /// Load a file using the given filename. Returns true if successful.
+ bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the given filename. Returns true if successful.
+ bool SaveFile( const char * filename ) const;
+
+ #ifdef TIXML_USE_STL
+ bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
+ {
+ StringToBuffer f( filename );
+ return ( f.buffer && LoadFile( f.buffer, encoding ));
+ }
+ bool SaveFile( const std::string& filename ) const ///< STL std::string version.
+ {
+ StringToBuffer f( filename );
+ return ( f.buffer && SaveFile( f.buffer ));
+ }
+ #endif
+
+ /** Parse the given null terminated block of xml data. Passing in an encoding to this
+ method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+ to use that encoding, regardless of what TinyXml might otherwise try to detect.
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+ /** Get the root element -- the only top level element -- of the document.
+ In well formed XML, there should only be one. TinyXml is tolerant of
+ multiple elements at the document level.
+ */
+ TiXmlElement* RootElement() const { return FirstChildElement(); }
+
+ /** If an error occurs, Error will be set to true. Also,
+ - The ErrorId() will contain the integer identifier of the error (not generally useful)
+ - The ErrorDesc() method will return the name of the error. (very useful)
+ - The ErrorRow() and ErrorCol() will return the location of the error (if known)
+ */
+ bool Error() const { return error; }
+
+ /// Contains a textual (english) description of the error if one occurs.
+ const char * ErrorDesc() const { return errorDesc.c_str (); }
+
+ /** Generally, you probably want the error string ( ErrorDesc() ). But if you
+ prefer the ErrorId, this function will fetch it.
+ */
+ const int ErrorId() const { return errorId; }
+
+ /** Returns the location (if known) of the error. The first column is column 1,
+ and the first row is row 1. A value of 0 means the row and column wasn't applicable
+ (memory errors, for example, have no row/column) or the parser lost the error. (An
+ error in the error reporting, in that case.)
+
+ @sa SetTabSize, Row, Column
+ */
+ int ErrorRow() { return errorLocation.row+1; }
+ int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
+
+ /** By calling this method, with a tab size
+ greater than 0, the row and column of each node and attribute is stored
+ when the file is loaded. Very useful for tracking the DOM back in to
+ the source file.
+
+ The tab size is required for calculating the location of nodes. If not
+ set, the default of 4 is used. The tabsize is set per document. Setting
+ the tabsize to 0 disables row/column tracking.
+
+ Note that row and column tracking is not supported when using operator>>.
+
+ The tab size needs to be enabled before the parse or load. Correct usage:
+ @verbatim
+ TiXmlDocument doc;
+ doc.SetTabSize( 8 );
+ doc.Load( "myfile.xml" );
+ @endverbatim
+
+ @sa Row, Column
+ */
+ void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
+
+ int TabSize() const { return tabsize; }
+
+ /** If you have handled the error, it can be reset with this call. The error
+ state is automatically cleared if you Parse a new XML block.
+ */
+ void ClearError() { error = false;
+ errorId = 0;
+ errorDesc = "";
+ errorLocation.row = errorLocation.col = 0;
+ //errorLocation.last = 0;
+ }
+
+ /** Dump the document to standard out. */
+ void Print() const { Print( stdout, 0 ); }
+
+ /// Print this Document to a FILE stream.
+ virtual void Print( FILE* cfile, int depth = 0 ) const;
+ // [internal use]
+ void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
protected :
- virtual void StreamOut ( TIXML_OSTREAM * out) const;
- // [internal use]
- virtual TiXmlNode* Clone() const;
-#ifdef TIXML_USE_STL
-
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
-#endif
+ virtual void StreamOut ( TIXML_OSTREAM * out) const;
+ // [internal use]
+ virtual TiXmlNode* Clone() const;
+ #ifdef TIXML_USE_STL
+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ #endif
private:
- void CopyTo( TiXmlDocument* target ) const;
+ void CopyTo( TiXmlDocument* target ) const;
- bool error;
- int errorId;
- TIXML_STRING errorDesc;
- int tabsize;
- TiXmlCursor errorLocation;
+ bool error;
+ int errorId;
+ TIXML_STRING errorDesc;
+ int tabsize;
+ TiXmlCursor errorLocation;
};
@@ -1456,7 +1229,7 @@ private:
A TiXmlHandle is a class that wraps a node pointer with null checks; this is
an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
DOM structure. It is a separate utility class.
-
+
Take an example:
@verbatim
<Document>
@@ -1466,10 +1239,10 @@ private:
</Element>
<Document>
@endverbatim
-
+
Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
easy to write a *lot* of code that looks like:
-
+
@verbatim
TiXmlElement* root = document.FirstChildElement( "Document" );
if ( root )
@@ -1485,11 +1258,11 @@ private:
{
// Finally do something useful.
@endverbatim
-
+
And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
and correct to use:
-
+
@verbatim
TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
@@ -1497,16 +1270,16 @@ private:
{
// do something useful
@endverbatim
-
+
Which is MUCH more concise and useful.
-
+
It is also safe to copy handles - internally they are nothing more than node pointers.
@verbatim
TiXmlHandle handleCopy = handle;
@endverbatim
-
+
What they should not be used for is iteration:
-
+
@verbatim
int i=0;
while ( true )
@@ -1518,14 +1291,14 @@ private:
++i;
}
@endverbatim
-
+
It seems reasonable, but it is in fact two embedded while loops. The Child method is
a linear walk to find the element, so this code would iterate much more than it needs
to. Instead, prefer:
-
+
@verbatim
TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
-
+
for( child; child; child=child->NextSiblingElement() )
{
// do something
@@ -1535,94 +1308,59 @@ private:
class TiXmlHandle
{
public:
- /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
- TiXmlHandle( TiXmlNode* node )
- {
- this->node = node;
- }
- /// Copy constructor
- TiXmlHandle( const TiXmlHandle& ref )
- {
- this->node = ref.node;
- }
- TiXmlHandle operator=( const TiXmlHandle& ref )
- {
- this->node = ref.node;
- return *this;
- }
-
- /// Return a handle to the first child node.
- TiXmlHandle FirstChild() const;
- /// Return a handle to the first child node with the given name.
- TiXmlHandle FirstChild( const char * value ) const;
- /// Return a handle to the first child element.
- TiXmlHandle FirstChildElement() const;
- /// Return a handle to the first child element with the given name.
- TiXmlHandle FirstChildElement( const char * value ) const;
-
- /** Return a handle to the "index" child with the given name.
- The first child is 0, the second 1, etc.
- */
- TiXmlHandle Child( const char* value, int index ) const;
- /** Return a handle to the "index" child.
- The first child is 0, the second 1, etc.
- */
- TiXmlHandle Child( int index ) const;
- /** Return a handle to the "index" child element with the given name.
- The first child element is 0, the second 1, etc. Note that only TiXmlElements
- are indexed: other types are not counted.
- */
- TiXmlHandle ChildElement( const char* value, int index ) const;
- /** Return a handle to the "index" child element.
- The first child element is 0, the second 1, etc. Note that only TiXmlElements
- are indexed: other types are not counted.
- */
- TiXmlHandle ChildElement( int index ) const;
-
-#ifdef TIXML_USE_STL
-
- TiXmlHandle FirstChild( const std::string& _value ) const
- {
- return FirstChild( _value.c_str() );
- }
- TiXmlHandle FirstChildElement( const std::string& _value ) const
- {
- return FirstChildElement( _value.c_str() );
- }
-
- TiXmlHandle Child( const std::string& _value, int index ) const
- {
- return Child( _value.c_str(), index );
- }
- TiXmlHandle ChildElement( const std::string& _value, int index ) const
- {
- return ChildElement( _value.c_str(), index );
- }
-#endif
-
- /// Return the handle as a TiXmlNode. This may return null.
- TiXmlNode* Node() const
- {
- return node;
- }
- /// Return the handle as a TiXmlElement. This may return null.
- TiXmlElement* Element() const
- {
- return ( ( node && node->ToElement() ) ? node->ToElement() : 0 );
- }
- /// Return the handle as a TiXmlText. This may return null.
- TiXmlText* Text() const
- {
- return ( ( node && node->ToText() ) ? node->ToText() : 0 );
- }
- /// Return the handle as a TiXmlUnknown. This may return null;
- TiXmlUnknown* Unknown() const
- {
- return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 );
- }
+ /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+ TiXmlHandle( TiXmlNode* node ) { this->node = node; }
+ /// Copy constructor
+ TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
+ TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+ /// Return a handle to the first child node.
+ TiXmlHandle FirstChild() const;
+ /// Return a handle to the first child node with the given name.
+ TiXmlHandle FirstChild( const char * value ) const;
+ /// Return a handle to the first child element.
+ TiXmlHandle FirstChildElement() const;
+ /// Return a handle to the first child element with the given name.
+ TiXmlHandle FirstChildElement( const char * value ) const;
+
+ /** Return a handle to the "index" child with the given name.
+ The first child is 0, the second 1, etc.
+ */
+ TiXmlHandle Child( const char* value, int index ) const;
+ /** Return a handle to the "index" child.
+ The first child is 0, the second 1, etc.
+ */
+ TiXmlHandle Child( int index ) const;
+ /** Return a handle to the "index" child element with the given name.
+ The first child element is 0, the second 1, etc. Note that only TiXmlElements
+ are indexed: other types are not counted.
+ */
+ TiXmlHandle ChildElement( const char* value, int index ) const;
+ /** Return a handle to the "index" child element.
+ The first child element is 0, the second 1, etc. Note that only TiXmlElements
+ are indexed: other types are not counted.
+ */
+ TiXmlHandle ChildElement( int index ) const;
+
+ #ifdef TIXML_USE_STL
+ TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
+ TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
+
+ TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
+ TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
+ #endif
+
+ /// Return the handle as a TiXmlNode. This may return null.
+ TiXmlNode* Node() const { return node; }
+ /// Return the handle as a TiXmlElement. This may return null.
+ TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+ /// Return the handle as a TiXmlText. This may return null.
+ TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+ /// Return the handle as a TiXmlUnknown. This may return null;
+ TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
private:
- TiXmlNode* node;
+ TiXmlNode* node;
};
diff --git a/src/contrib/xml/tinyxmlerror.cpp b/src/contrib/xml/tinyxmlerror.cpp
index 9243e89..b04add7 100644
--- a/src/contrib/xml/tinyxmlerror.cpp
+++ b/src/contrib/xml/tinyxmlerror.cpp
@@ -1,23 +1,23 @@
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
-
+
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
-
+
3. This notice may not be removed or altered from any source
distribution.
*/
@@ -32,20 +32,20 @@ distribution.
//
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
- {
- "No error",
- "Error",
- "Failed to open file",
- "Memory allocation failed.",
- "Error parsing Element.",
- "Failed to read Element name",
- "Error reading Element value.",
- "Error reading Attributes.",
- "Error: empty tag.",
- "Error reading end tag.",
- "Error parsing Unknown.",
- "Error parsing Comment.",
- "Error parsing Declaration.",
- "Error document empty.",
- "Error null (0) or unexpected EOF found in input stream.",
- };
+{
+ "No error",
+ "Error",
+ "Failed to open file",
+ "Memory allocation failed.",
+ "Error parsing Element.",
+ "Failed to read Element name",
+ "Error reading Element value.",
+ "Error reading Attributes.",
+ "Error: empty tag.",
+ "Error reading end tag.",
+ "Error parsing Unknown.",
+ "Error parsing Comment.",
+ "Error parsing Declaration.",
+ "Error document empty.",
+ "Error null (0) or unexpected EOF found in input stream.",
+};
diff --git a/src/contrib/xml/tinyxmlparser.cpp b/src/contrib/xml/tinyxmlparser.cpp
index 9c696b6..f06d1cd 100644
--- a/src/contrib/xml/tinyxmlparser.cpp
+++ b/src/contrib/xml/tinyxmlparser.cpp
@@ -1,23 +1,23 @@
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
-
+
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
-
+
3. This notice may not be removed or altered from any source
distribution.
*/
@@ -29,1525 +29,1465 @@ distribution.
// Note tha "PutString" hardcodes the same list. This
// is less flexible than it appears. Changing the entries
-// or order will break putstring.
-TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
- {
- { "&amp;", 5, '&' },
- { "&lt;", 4, '<' },
- { "&gt;", 4, '>' },
- { "&quot;", 6, '\"' },
- { "&apos;", 6, '\'' }
- };
+// or order will break putstring.
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
+{
+ { "&amp;", 5, '&' },
+ { "&lt;", 4, '<' },
+ { "&gt;", 4, '>' },
+ { "&quot;", 6, '\"' },
+ { "&apos;", 6, '\'' }
+};
// Bunch of unicode info at:
// http://www.unicode.org/faq/utf_bom.html
// Including the basic of this table, which determines the #bytes in the
// sequence from the lead byte. 1 placed for invalid sequences --
// although the result will be junk, pass it through as much as possible.
-// Beware of the non-characters in UTF-8:
+// Beware of the non-characters in UTF-8:
// ef bb bf (Microsoft "lead bytes")
// ef bf be
-// ef bf bf
-
-
-
-const int TiXmlBase::utf8ByteTable[256] =
- {
- // 0 1 2 3 4 5 6 7 8 9 a b c d e f
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
- 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte
- 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
- };
+// ef bf bf
+
+
+
+const int TiXmlBase::utf8ByteTable[256] =
+{
+ // 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte
+ 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
{
- const unsigned long BYTE_MASK = 0xBF;
- const unsigned long BYTE_MARK = 0x80;
- const unsigned long FIRST_BYTE_MARK[7] =
- {
- 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
- };
-
- if (input < 0x80)
- *length = 1;
- else if ( input < 0x800 )
- *length = 2;
- else if ( input < 0x10000 )
- *length = 3;
- else if ( input < 0x200000 )
- *length = 4;
- else
- {
- *length = 0;
- return;
- } // This code won't covert this correctly anyway.
-
- output += *length;
-
- // Scary scary fall throughs.
- switch (*length)
- {
- case 4:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 3:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 2:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 1:
- --output;
- *output = (char)(input | FIRST_BYTE_MARK[*length]);
- }
+ const unsigned long BYTE_MASK = 0xBF;
+ const unsigned long BYTE_MARK = 0x80;
+ const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+ if (input < 0x80)
+ *length = 1;
+ else if ( input < 0x800 )
+ *length = 2;
+ else if ( input < 0x10000 )
+ *length = 3;
+ else if ( input < 0x200000 )
+ *length = 4;
+ else
+ { *length = 0; return; } // This code won't covert this correctly anyway.
+
+ output += *length;
+
+ // Scary scary fall throughs.
+ switch (*length)
+ {
+ case 4:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 3:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 2:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 1:
+ --output;
+ *output = (char)(input | FIRST_BYTE_MARK[*length]);
+ }
}
/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding encoding )
{
- // This will only work for low-ascii, everything else is assumed to be a valid
- // letter. I'm not sure this is the best approach, but it is quite tricky trying
- // to figure out alhabetical vs. not across encoding. So take a very
- // conservative approach.
-
- // if ( encoding == TIXML_ENCODING_UTF8 )
- // {
- if ( anyByte < 127 )
- return isalpha( anyByte );
- else
- return 1; // What else to do? The unicode set is huge...get the english ones right.
- // }
- // else
- // {
- // return isalpha( anyByte );
- // }
+ // This will only work for low-ascii, everything else is assumed to be a valid
+ // letter. I'm not sure this is the best approach, but it is quite tricky trying
+ // to figure out alhabetical vs. not across encoding. So take a very
+ // conservative approach.
+
+// if ( encoding == TIXML_ENCODING_UTF8 )
+// {
+ if ( anyByte < 127 )
+ return isalpha( anyByte );
+ else
+ return 1; // What else to do? The unicode set is huge...get the english ones right.
+// }
+// else
+// {
+// return isalpha( anyByte );
+// }
}
/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding )
{
- // This will only work for low-ascii, everything else is assumed to be a valid
- // letter. I'm not sure this is the best approach, but it is quite tricky trying
- // to figure out alhabetical vs. not across encoding. So take a very
- // conservative approach.
-
- // if ( encoding == TIXML_ENCODING_UTF8 )
- // {
- if ( anyByte < 127 )
- return isalnum( anyByte );
- else
- return 1; // What else to do? The unicode set is huge...get the english ones right.
- // }
- // else
- // {
- // return isalnum( anyByte );
- // }
+ // This will only work for low-ascii, everything else is assumed to be a valid
+ // letter. I'm not sure this is the best approach, but it is quite tricky trying
+ // to figure out alhabetical vs. not across encoding. So take a very
+ // conservative approach.
+
+// if ( encoding == TIXML_ENCODING_UTF8 )
+// {
+ if ( anyByte < 127 )
+ return isalnum( anyByte );
+ else
+ return 1; // What else to do? The unicode set is huge...get the english ones right.
+// }
+// else
+// {
+// return isalnum( anyByte );
+// }
}
class TiXmlParsingData
{
- friend class TiXmlDocument;
-public:
- void Stamp( const char* now, TiXmlEncoding encoding );
-
- const TiXmlCursor& Cursor()
- {
- return cursor;
- }
-
-private:
- // Only used by the document!
- TiXmlParsingData( const char* start, int _tabsize, int row, int col )
- {
- assert( start );
- stamp = start;
- tabsize = _tabsize;
- cursor.row = row;
- cursor.col = col;
- }
-
- TiXmlCursor cursor;
- const char* stamp;
- int tabsize;
+ friend class TiXmlDocument;
+ public:
+ void Stamp( const char* now, TiXmlEncoding encoding );
+
+ const TiXmlCursor& Cursor() { return cursor; }
+
+ private:
+ // Only used by the document!
+ TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+ {
+ assert( start );
+ stamp = start;
+ tabsize = _tabsize;
+ cursor.row = row;
+ cursor.col = col;
+ }
+
+ TiXmlCursor cursor;
+ const char* stamp;
+ int tabsize;
};
void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
{
- assert( now );
-
- // Do nothing if the tabsize is 0.
- if ( tabsize < 1 )
- {
- return;
- }
-
- // Get the current row, column.
- int row = cursor.row;
- int col = cursor.col;
- const char* p = stamp;
- assert( p );
-
- while ( p < now )
- {
- // Code contributed by Fletcher Dunn: (modified by lee)
- switch (*p)
- {
- case 0:
- // We *should* never get here, but in case we do, don't
- // advance past the terminating null character, ever
- return;
-
- case '\r':
- // bump down to the next line
- ++row;
- col = 0;
- // Eat the character
- ++p;
-
- // Check for \r\n sequence, and treat this as a single character
- if (*p == '\n')
- {
- ++p;
- }
- break;
-
- case '\n':
- // bump down to the next line
- ++row;
- col = 0;
-
- // Eat the character
- ++p;
-
- // Check for \n\r sequence, and treat this as a single
- // character. (Yes, this bizarre thing does occur still
- // on some arcane platforms...)
- if (*p == '\r')
- {
- ++p;
- }
- break;
-
- case '\t':
- // Eat the character
- ++p;
-
- // Skip to next tab stop
- col = (col / tabsize + 1) * tabsize;
- break;
-
- case (char)(0xef):
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- if ( *(p+1) && *(p+2) )
- {
- // In these cases, don't advance the column. These are
- // 0-width spaces.
- if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) )
- p += 3;
- else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) )
- p += 3;
- else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) )
- p += 3;
- else
- {
- p +=3;
- ++col;
- } // A normal character.
- }
- }
- else
- {
- ++p;
- ++col;
- }
- break;
-
- default:
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- // Eat the 1 to 4 byte utf8 character.
- int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)];
- if ( step == 0 )
- step = 1; // Error case from bad encoding, but handle gracefully.
- p += step;
-
- // Just advance one column, of course.
- ++col;
- }
- else
- {
- ++p;
- ++col;
- }
- break;
- }
- }
- cursor.row = row;
- cursor.col = col;
- assert( cursor.row >= -1 );
- assert( cursor.col >= -1 );
- stamp = p;
- assert( stamp );
+ assert( now );
+
+ // Do nothing if the tabsize is 0.
+ if ( tabsize < 1 )
+ {
+ return;
+ }
+
+ // Get the current row, column.
+ int row = cursor.row;
+ int col = cursor.col;
+ const char* p = stamp;
+ assert( p );
+
+ while ( p < now )
+ {
+ // Code contributed by Fletcher Dunn: (modified by lee)
+ switch (*p) {
+ case 0:
+ // We *should* never get here, but in case we do, don't
+ // advance past the terminating null character, ever
+ return;
+
+ case '\r':
+ // bump down to the next line
+ ++row;
+ col = 0;
+ // Eat the character
+ ++p;
+
+ // Check for \r\n sequence, and treat this as a single character
+ if (*p == '\n') {
+ ++p;
+ }
+ break;
+
+ case '\n':
+ // bump down to the next line
+ ++row;
+ col = 0;
+
+ // Eat the character
+ ++p;
+
+ // Check for \n\r sequence, and treat this as a single
+ // character. (Yes, this bizarre thing does occur still
+ // on some arcane platforms...)
+ if (*p == '\r') {
+ ++p;
+ }
+ break;
+
+ case '\t':
+ // Eat the character
+ ++p;
+
+ // Skip to next tab stop
+ col = (col / tabsize + 1) * tabsize;
+ break;
+
+ case (char)(0xef):
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ if ( *(p+1) && *(p+2) )
+ {
+ // In these cases, don't advance the column. These are
+ // 0-width spaces.
+ if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) )
+ p += 3;
+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) )
+ p += 3;
+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) )
+ p += 3;
+ else
+ { p +=3; ++col; } // A normal character.
+ }
+ }
+ else
+ {
+ ++p;
+ ++col;
+ }
+ break;
+
+ default:
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ // Eat the 1 to 4 byte utf8 character.
+ int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)];
+ if ( step == 0 )
+ step = 1; // Error case from bad encoding, but handle gracefully.
+ p += step;
+
+ // Just advance one column, of course.
+ ++col;
+ }
+ else
+ {
+ ++p;
+ ++col;
+ }
+ break;
+ }
+ }
+ cursor.row = row;
+ cursor.col = col;
+ assert( cursor.row >= -1 );
+ assert( cursor.col >= -1 );
+ stamp = p;
+ assert( stamp );
}
const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
{
- if ( !p || !*p )
- {
- return 0;
- }
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- while ( *p )
- {
- // Skip the stupid Microsoft UTF-8 Byte order marks
- if ( *(p+0)==(char) 0xef
- && *(p+1)==(char) 0xbb
- && *(p+2)==(char) 0xbf )
- {
- p += 3;
- continue;
- }
- else if(*(p+0)==(char) 0xef
- && *(p+1)==(char) 0xbf
- && *(p+2)==(char) 0xbe )
- {
- p += 3;
- continue;
- }
- else if(*(p+0)==(char) 0xef
- && *(p+1)==(char) 0xbf
- && *(p+2)==(char) 0xbf )
- {
- p += 3;
- continue;
- }
-
- if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space.
- ++p;
- else
- break;
- }
- }
- else
- {
- while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
- ++p;
- }
-
- return p;
+ if ( !p || !*p )
+ {
+ return 0;
+ }
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ while ( *p )
+ {
+ // Skip the stupid Microsoft UTF-8 Byte order marks
+ if ( *(p+0)==(char) 0xef
+ && *(p+1)==(char) 0xbb
+ && *(p+2)==(char) 0xbf )
+ {
+ p += 3;
+ continue;
+ }
+ else if(*(p+0)==(char) 0xef
+ && *(p+1)==(char) 0xbf
+ && *(p+2)==(char) 0xbe )
+ {
+ p += 3;
+ continue;
+ }
+ else if(*(p+0)==(char) 0xef
+ && *(p+1)==(char) 0xbf
+ && *(p+2)==(char) 0xbf )
+ {
+ p += 3;
+ continue;
+ }
+
+ if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space.
+ ++p;
+ else
+ break;
+ }
+ }
+ else
+ {
+ while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
+ ++p;
+ }
+
+ return p;
}
#ifdef TIXML_USE_STL
/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- for( ;; )
- {
- if ( !in->good() )
- return false;
-
- int c = in->peek();
- // At this scope, we can't get to a document. So fail silently.
- if ( !IsWhiteSpace( c ) || c <= 0 )
- return true;
-
- *tag += (char) in->get
- ();
- }
+ for( ;; )
+ {
+ if ( !in->good() ) return false;
+
+ int c = in->peek();
+ // At this scope, we can't get to a document. So fail silently.
+ if ( !IsWhiteSpace( c ) || c <= 0 )
+ return true;
+
+ *tag += (char) in->get();
+ }
}
/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag )
{
- //assert( character > 0 && character < 128 ); // else it won't work in utf-8
- while ( in->good() )
- {
- int c = in->peek();
- if ( c == character )
- return true;
- if ( c <= 0 ) // Silent failure: can't get document at this scope
- return false;
-
- in->get
- ();
- *tag += (char) c;
- }
- return false;
+ //assert( character > 0 && character < 128 ); // else it won't work in utf-8
+ while ( in->good() )
+ {
+ int c = in->peek();
+ if ( c == character )
+ return true;
+ if ( c <= 0 ) // Silent failure: can't get document at this scope
+ return false;
+
+ in->get();
+ *tag += (char) c;
+ }
+ return false;
}
#endif
const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
{
- *name = "";
- assert( p );
-
- // Names start with letters or underscores.
- // Of course, in unicode, tinyxml has no idea what a letter *is*. The
- // algorithm is generous.
- //
- // After that, they can be letters, underscores, numbers,
- // hyphens, or colons. (Colons are valid ony for namespaces,
- // but tinyxml can't tell namespaces from names.)
- if ( p && *p
- && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
- {
- while( p && *p
- && ( IsAlphaNum( (unsigned char ) *p, encoding )
- || *p == '_'
- || *p == '-'
- || *p == '.'
- || *p == ':' ) )
- {
- (*name) += *p;
- ++p;
- }
- return p;
- }
- return 0;
+ *name = "";
+ assert( p );
+
+ // Names start with letters or underscores.
+ // Of course, in unicode, tinyxml has no idea what a letter *is*. The
+ // algorithm is generous.
+ //
+ // After that, they can be letters, underscores, numbers,
+ // hyphens, or colons. (Colons are valid ony for namespaces,
+ // but tinyxml can't tell namespaces from names.)
+ if ( p && *p
+ && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+ {
+ while( p && *p
+ && ( IsAlphaNum( (unsigned char ) *p, encoding )
+ || *p == '_'
+ || *p == '-'
+ || *p == '.'
+ || *p == ':' ) )
+ {
+ (*name) += *p;
+ ++p;
+ }
+ return p;
+ }
+ return 0;
}
const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
{
- // Presume an entity, and pull it out.
- TIXML_STRING ent;
- int i;
- *length = 0;
-
- if ( *(p+1) && *(p+1) == '#' && *(p+2) )
- {
- unsigned long ucs = 0;
- unsigned delta = 0;
- unsigned mult = 1;
-
- if ( *(p+2) == 'x' )
- {
- // Hexadecimal.
- if ( !*(p+3) )
- return 0;
-
- const char* q = p+3;
- q = strchr( q, ';' );
-
- if ( !q || !*q )
- return 0;
-
- delta = q-p;
- --q;
-
- while ( *q != 'x' )
- {
- if ( *q >= '0' && *q <= '9' )
- ucs += mult * (*q - '0');
- else if ( *q >= 'a' && *q <= 'f' )
- ucs += mult * (*q - 'a' + 10);
- else if ( *q >= 'A' && *q <= 'F' )
- ucs += mult * (*q - 'A' + 10 );
- else
- return 0;
- mult *= 16;
- --q;
- }
- }
- else
- {
- // Decimal.
- if ( !*(p+2) )
- return 0;
-
- const char* q = p+2;
- q = strchr( q, ';' );
-
- if ( !q || !*q )
- return 0;
-
- delta = q-p;
- --q;
-
- while ( *q != '#' )
- {
- if ( *q >= '0' && *q <= '9' )
- ucs += mult * (*q - '0');
- else
- return 0;
- mult *= 10;
- --q;
- }
- }
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- // convert the UCS to UTF-8
- ConvertUTF32ToUTF8( ucs, value, length );
- }
- else
- {
- *value = (char)ucs;
- *length = 1;
- }
- return p + delta + 1;
- }
-
- // Now try to match it.
- for( i=0; i<NUM_ENTITY; ++i )
- {
- if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
- {
- assert( strlen( entity[i].str ) == entity[i].strLength );
- *value = entity[i].chr;
- *length = 1;
- return ( p + entity[i].strLength );
- }
- }
-
- // So it wasn't an entity, its unrecognized, or something like that.
- *value = *p; // Don't put back the last one, since we return it!
- return p+1;
+ // Presume an entity, and pull it out.
+ TIXML_STRING ent;
+ int i;
+ *length = 0;
+
+ if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+ {
+ unsigned long ucs = 0;
+ unsigned delta = 0;
+ unsigned mult = 1;
+
+ if ( *(p+2) == 'x' )
+ {
+ // Hexadecimal.
+ if ( !*(p+3) ) return 0;
+
+ const char* q = p+3;
+ q = strchr( q, ';' );
+
+ if ( !q || !*q ) return 0;
+
+ delta = q-p;
+ --q;
+
+ while ( *q != 'x' )
+ {
+ if ( *q >= '0' && *q <= '9' )
+ ucs += mult * (*q - '0');
+ else if ( *q >= 'a' && *q <= 'f' )
+ ucs += mult * (*q - 'a' + 10);
+ else if ( *q >= 'A' && *q <= 'F' )
+ ucs += mult * (*q - 'A' + 10 );
+ else
+ return 0;
+ mult *= 16;
+ --q;
+ }
+ }
+ else
+ {
+ // Decimal.
+ if ( !*(p+2) ) return 0;
+
+ const char* q = p+2;
+ q = strchr( q, ';' );
+
+ if ( !q || !*q ) return 0;
+
+ delta = q-p;
+ --q;
+
+ while ( *q != '#' )
+ {
+ if ( *q >= '0' && *q <= '9' )
+ ucs += mult * (*q - '0');
+ else
+ return 0;
+ mult *= 10;
+ --q;
+ }
+ }
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ // convert the UCS to UTF-8
+ ConvertUTF32ToUTF8( ucs, value, length );
+ }
+ else
+ {
+ *value = (char)ucs;
+ *length = 1;
+ }
+ return p + delta + 1;
+ }
+
+ // Now try to match it.
+ for( i=0; i<NUM_ENTITY; ++i )
+ {
+ if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+ {
+ assert( strlen( entity[i].str ) == entity[i].strLength );
+ *value = entity[i].chr;
+ *length = 1;
+ return ( p + entity[i].strLength );
+ }
+ }
+
+ // So it wasn't an entity, its unrecognized, or something like that.
+ *value = *p; // Don't put back the last one, since we return it!
+ return p+1;
}
bool TiXmlBase::StringEqual( const char* p,
- const char* tag,
- bool ignoreCase,
- TiXmlEncoding encoding )
+ const char* tag,
+ bool ignoreCase,
+ TiXmlEncoding encoding )
{
- assert( p );
- assert( tag );
- if ( !p || !*p )
- {
- assert( 0 );
- return false;
- }
-
- const char* q = p;
-
- if ( ignoreCase )
- {
- while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
- {
- ++q;
- ++tag;
- }
-
- if ( *tag == 0 )
- return true;
- }
- else
- {
- while ( *q && *tag && *q == *tag )
- {
- ++q;
- ++tag;
- }
-
- if ( *tag == 0 ) // Have we found the end of the tag, and everything equal?
- return true;
- }
- return false;
+ assert( p );
+ assert( tag );
+ if ( !p || !*p )
+ {
+ assert( 0 );
+ return false;
+ }
+
+ const char* q = p;
+
+ if ( ignoreCase )
+ {
+ while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+ {
+ ++q;
+ ++tag;
+ }
+
+ if ( *tag == 0 )
+ return true;
+ }
+ else
+ {
+ while ( *q && *tag && *q == *tag )
+ {
+ ++q;
+ ++tag;
+ }
+
+ if ( *tag == 0 ) // Have we found the end of the tag, and everything equal?
+ return true;
+ }
+ return false;
}
-const char* TiXmlBase::ReadText( const char* p,
- TIXML_STRING * text,
- bool trimWhiteSpace,
- const char* endTag,
- bool caseInsensitive,
- TiXmlEncoding encoding )
+const char* TiXmlBase::ReadText( const char* p,
+ TIXML_STRING * text,
+ bool trimWhiteSpace,
+ const char* endTag,
+ bool caseInsensitive,
+ TiXmlEncoding encoding )
{
- *text = "";
- if ( !trimWhiteSpace // certain tags always keep whitespace
- || !condenseWhiteSpace ) // if true, whitespace is always kept
- {
- // Keep all the white space.
- while ( p && *p
- && !StringEqual( p, endTag, caseInsensitive, encoding )
- )
- {
- int len;
- char cArr[4] = { 0, 0, 0, 0 };
- p = GetChar( p, cArr, &len, encoding );
- text->append( cArr, len );
- }
- }
- else
- {
- bool whitespace = false;
-
- // Remove leading white space:
- p = SkipWhiteSpace( p, encoding );
- while ( p && *p
- && !StringEqual( p, endTag, caseInsensitive, encoding ) )
- {
- if ( *p == '\r' || *p == '\n' )
- {
- whitespace = true;
- ++p;
- }
- else if ( IsWhiteSpace( *p ) )
- {
- whitespace = true;
- ++p;
- }
- else
- {
- // If we've found whitespace, add it before the
- // new character. Any whitespace just becomes a space.
- if ( whitespace )
- {
- (*text) += ' ';
- whitespace = false;
- }
- int len;
- char cArr[4] = { 0, 0, 0, 0 };
- p = GetChar( p, cArr, &len, encoding );
- if ( len == 1 )
- (*text) += cArr[0]; // more efficient
- else
- text->append( cArr, len );
- }
- }
- }
- return p + strlen( endTag );
+ *text = "";
+ if ( !trimWhiteSpace // certain tags always keep whitespace
+ || !condenseWhiteSpace ) // if true, whitespace is always kept
+ {
+ // Keep all the white space.
+ while ( p && *p
+ && !StringEqual( p, endTag, caseInsensitive, encoding )
+ )
+ {
+ int len;
+ char cArr[4] = { 0, 0, 0, 0 };
+ p = GetChar( p, cArr, &len, encoding );
+ text->append( cArr, len );
+ }
+ }
+ else
+ {
+ bool whitespace = false;
+
+ // Remove leading white space:
+ p = SkipWhiteSpace( p, encoding );
+ while ( p && *p
+ && !StringEqual( p, endTag, caseInsensitive, encoding ) )
+ {
+ if ( *p == '\r' || *p == '\n' )
+ {
+ whitespace = true;
+ ++p;
+ }
+ else if ( IsWhiteSpace( *p ) )
+ {
+ whitespace = true;
+ ++p;
+ }
+ else
+ {
+ // If we've found whitespace, add it before the
+ // new character. Any whitespace just becomes a space.
+ if ( whitespace )
+ {
+ (*text) += ' ';
+ whitespace = false;
+ }
+ int len;
+ char cArr[4] = { 0, 0, 0, 0 };
+ p = GetChar( p, cArr, &len, encoding );
+ if ( len == 1 )
+ (*text) += cArr[0]; // more efficient
+ else
+ text->append( cArr, len );
+ }
+ }
+ }
+ return p + strlen( endTag );
}
#ifdef TIXML_USE_STL
void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- // The basic issue with a document is that we don't know what we're
- // streaming. Read something presumed to be a tag (and hope), then
- // identify it, and call the appropriate stream method on the tag.
- //
- // This "pre-streaming" will never read the closing ">" so the
- // sub-tag can orient itself.
-
- if ( !StreamTo( in, '<', tag ) )
- {
- SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
-
- while ( in->good() )
- {
- int tagIndex = (int) tag->length();
- while ( in->good() && in->peek() != '>' )
- {
- int c = in->get
- ();
- if ( c <= 0 )
- {
- SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- break;
- }
- (*tag) += (char) c;
- }
-
- if ( in->good() )
- {
- // We now have something we presume to be a node of
- // some sort. Identify it, and call the node to
- // continue streaming.
- TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
-
- if ( node )
- {
- node->StreamIn( in, tag );
- bool isElement = node->ToElement() != 0;
- delete node;
- node = 0;
-
- // If this is the root element, we're done. Parsing will be
- // done by the >> operator.
- if ( isElement )
- {
- return;
- }
- }
- else
- {
- SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
- }
- }
- // We should have returned sooner.
- SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+ // The basic issue with a document is that we don't know what we're
+ // streaming. Read something presumed to be a tag (and hope), then
+ // identify it, and call the appropriate stream method on the tag.
+ //
+ // This "pre-streaming" will never read the closing ">" so the
+ // sub-tag can orient itself.
+
+ if ( !StreamTo( in, '<', tag ) )
+ {
+ SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+
+ while ( in->good() )
+ {
+ int tagIndex = (int) tag->length();
+ while ( in->good() && in->peek() != '>' )
+ {
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ break;
+ }
+ (*tag) += (char) c;
+ }
+
+ if ( in->good() )
+ {
+ // We now have something we presume to be a node of
+ // some sort. Identify it, and call the node to
+ // continue streaming.
+ TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+ if ( node )
+ {
+ node->StreamIn( in, tag );
+ bool isElement = node->ToElement() != 0;
+ delete node;
+ node = 0;
+
+ // If this is the root element, we're done. Parsing will be
+ // done by the >> operator.
+ if ( isElement )
+ {
+ return;
+ }
+ }
+ else
+ {
+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+ }
+ }
+ // We should have returned sooner.
+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
}
#endif
const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
{
- ClearError();
-
- // Parse away, at the document level. Since a document
- // contains nothing but other tags, most of what happens
- // here is skipping white space.
- if ( !p || !*p )
- {
- SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
- return 0;
- }
-
- // Note that, for a document, this needs to come
- // before the while space skip, so that parsing
- // starts from the pointer we are given.
- location.Clear();
- if ( prevData )
- {
- location.row = prevData->cursor.row;
- location.col = prevData->cursor.col;
- }
- else
- {
- location.row = 0;
- location.col = 0;
- }
- TiXmlParsingData data( p, TabSize(), location.row, location.col );
- location = data.Cursor();
-
- if ( encoding == TIXML_ENCODING_UNKNOWN )
- {
- // Check for the Microsoft UTF-8 lead bytes.
- if ( *(p+0) && *(p+0) == (char)(0xef)
- && *(p+1) && *(p+1) == (char)(0xbb)
- && *(p+2) && *(p+2) == (char)(0xbf) )
- {
- encoding = TIXML_ENCODING_UTF8;
- }
- }
-
- p = SkipWhiteSpace( p, encoding );
- if ( !p )
- {
- SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
- return 0;
- }
-
- while ( p && *p )
- {
- TiXmlNode* node = Identify( p, encoding );
- if ( node )
- {
- p = node->Parse( p, &data, encoding );
- LinkEndChild( node );
- }
- else
- {
- break;
- }
-
- // Did we get encoding info?
- if ( encoding == TIXML_ENCODING_UNKNOWN
- && node->ToDeclaration() )
- {
- TiXmlDeclaration* dec = node->ToDeclaration();
- const char* enc = dec->Encoding();
- assert( enc );
-
- if ( *enc == 0 )
- encoding = TIXML_ENCODING_UTF8;
- else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
- encoding = TIXML_ENCODING_UTF8;
- else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
- encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
- else
- encoding = TIXML_ENCODING_LEGACY;
- }
+ ClearError();
+
+ // Parse away, at the document level. Since a document
+ // contains nothing but other tags, most of what happens
+ // here is skipping white space.
+ if ( !p || !*p )
+ {
+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return 0;
+ }
+
+ // Note that, for a document, this needs to come
+ // before the while space skip, so that parsing
+ // starts from the pointer we are given.
+ location.Clear();
+ if ( prevData )
+ {
+ location.row = prevData->cursor.row;
+ location.col = prevData->cursor.col;
+ }
+ else
+ {
+ location.row = 0;
+ location.col = 0;
+ }
+ TiXmlParsingData data( p, TabSize(), location.row, location.col );
+ location = data.Cursor();
+
+ if ( encoding == TIXML_ENCODING_UNKNOWN )
+ {
+ // Check for the Microsoft UTF-8 lead bytes.
+ if ( *(p+0) && *(p+0) == (char)(0xef)
+ && *(p+1) && *(p+1) == (char)(0xbb)
+ && *(p+2) && *(p+2) == (char)(0xbf) )
+ {
+ encoding = TIXML_ENCODING_UTF8;
+ }
+ }
p = SkipWhiteSpace( p, encoding );
- }
-
- // All is well.
- return p;
+ if ( !p )
+ {
+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return 0;
+ }
+
+ while ( p && *p )
+ {
+ TiXmlNode* node = Identify( p, encoding );
+ if ( node )
+ {
+ p = node->Parse( p, &data, encoding );
+ LinkEndChild( node );
+ }
+ else
+ {
+ break;
+ }
+
+ // Did we get encoding info?
+ if ( encoding == TIXML_ENCODING_UNKNOWN
+ && node->ToDeclaration() )
+ {
+ TiXmlDeclaration* dec = node->ToDeclaration();
+ const char* enc = dec->Encoding();
+ assert( enc );
+
+ if ( *enc == 0 )
+ encoding = TIXML_ENCODING_UTF8;
+ else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+ encoding = TIXML_ENCODING_UTF8;
+ else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+ encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
+ else
+ encoding = TIXML_ENCODING_LEGACY;
+ }
+
+ p = SkipWhiteSpace( p, encoding );
+ }
+
+ // All is well.
+ return p;
}
void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
- // The first error in a chain is more accurate - don't set again!
- if ( error )
- return;
-
- assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
- error = true;
- errorId = err;
- errorDesc = errorString[ errorId ];
-
- errorLocation.Clear();
- if ( pError && data )
- {
- //TiXmlParsingData data( pError, prevData );
- data->Stamp( pError, encoding );
- errorLocation = data->Cursor();
- }
+{
+ // The first error in a chain is more accurate - don't set again!
+ if ( error )
+ return;
+
+ assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+ error = true;
+ errorId = err;
+ errorDesc = errorString[ errorId ];
+
+ errorLocation.Clear();
+ if ( pError && data )
+ {
+ //TiXmlParsingData data( pError, prevData );
+ data->Stamp( pError, encoding );
+ errorLocation = data->Cursor();
+ }
}
TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
{
- TiXmlNode* returnNode = 0;
-
- p = SkipWhiteSpace( p, encoding );
- if( !p || !*p || *p != '<' )
- {
- return 0;
- }
-
- TiXmlDocument* doc = GetDocument();
- p = SkipWhiteSpace( p, encoding );
-
- if ( !p || !*p )
- {
- return 0;
- }
-
- // What is this thing?
- // - Elements start with a letter or underscore, but xml is reserved.
- // - Comments: <!--
- // - Decleration: <?xml
- // - Everthing else is unknown to tinyxml.
- //
-
- const char* xmlHeader =
- { "<?xml"
- };
- const char* commentHeader =
- { "<!--"
- };
- const char* dtdHeader =
- { "<!"
- };
-
- if ( StringEqual( p, xmlHeader, true, encoding ) )
- {
-#ifdef DEBUG_PARSER
- TIXML_LOG( "XML parsing Declaration\n" );
-#endif
-
- returnNode = new TiXmlDeclaration();
- }
- else if ( StringEqual( p, commentHeader, false, encoding ) )
- {
-#ifdef DEBUG_PARSER
- TIXML_LOG( "XML parsing Comment\n" );
-#endif
-
- returnNode = new TiXmlComment();
- }
- else if ( StringEqual( p, dtdHeader, false, encoding ) )
- {
-#ifdef DEBUG_PARSER
- TIXML_LOG( "XML parsing Unknown(1)\n" );
-#endif
-
- returnNode = new TiXmlUnknown();
- }
- else if ( IsAlpha( *(p+1), encoding )
- || *(p+1) == '_' )
- {
-#ifdef DEBUG_PARSER
- TIXML_LOG( "XML parsing Element\n" );
-#endif
-
- returnNode = new TiXmlElement( "" );
- }
- else
- {
-#ifdef DEBUG_PARSER
- TIXML_LOG( "XML parsing Unknown(2)\n" );
-#endif
-
- returnNode = new TiXmlUnknown();
- }
-
- if ( returnNode )
- {
- // Set the parent, so it can report errors
- returnNode->parent = this;
- }
- else
- {
- if ( doc )
- doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
- }
- return returnNode;
+ TiXmlNode* returnNode = 0;
+
+ p = SkipWhiteSpace( p, encoding );
+ if( !p || !*p || *p != '<' )
+ {
+ return 0;
+ }
+
+ TiXmlDocument* doc = GetDocument();
+ p = SkipWhiteSpace( p, encoding );
+
+ if ( !p || !*p )
+ {
+ return 0;
+ }
+
+ // What is this thing?
+ // - Elements start with a letter or underscore, but xml is reserved.
+ // - Comments: <!--
+ // - Decleration: <?xml
+ // - Everthing else is unknown to tinyxml.
+ //
+
+ const char* xmlHeader = { "<?xml" };
+ const char* commentHeader = { "<!--" };
+ const char* dtdHeader = { "<!" };
+
+ if ( StringEqual( p, xmlHeader, true, encoding ) )
+ {
+ #ifdef DEBUG_PARSER
+ TIXML_LOG( "XML parsing Declaration\n" );
+ #endif
+ returnNode = new TiXmlDeclaration();
+ }
+ else if ( StringEqual( p, commentHeader, false, encoding ) )
+ {
+ #ifdef DEBUG_PARSER
+ TIXML_LOG( "XML parsing Comment\n" );
+ #endif
+ returnNode = new TiXmlComment();
+ }
+ else if ( StringEqual( p, dtdHeader, false, encoding ) )
+ {
+ #ifdef DEBUG_PARSER
+ TIXML_LOG( "XML parsing Unknown(1)\n" );
+ #endif
+ returnNode = new TiXmlUnknown();
+ }
+ else if ( IsAlpha( *(p+1), encoding )
+ || *(p+1) == '_' )
+ {
+ #ifdef DEBUG_PARSER
+ TIXML_LOG( "XML parsing Element\n" );
+ #endif
+ returnNode = new TiXmlElement( "" );
+ }
+ else
+ {
+ #ifdef DEBUG_PARSER
+ TIXML_LOG( "XML parsing Unknown(2)\n" );
+ #endif
+ returnNode = new TiXmlUnknown();
+ }
+
+ if ( returnNode )
+ {
+ // Set the parent, so it can report errors
+ returnNode->parent = this;
+ }
+ else
+ {
+ if ( doc )
+ doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+ }
+ return returnNode;
}
#ifdef TIXML_USE_STL
void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag)
{
- // We're called with some amount of pre-parsing. That is, some of "this"
- // element is in "tag". Go ahead and stream to the closing ">"
- while( in->good() )
- {
- int c = in->get
- ();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
- (*tag) += (char) c ;
-
- if ( c == '>' )
- break;
- }
-
- if ( tag->length() < 3 )
- return;
-
- // Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
- // If not, identify and stream.
-
- if ( tag->at( tag->length() - 1 ) == '>'
- && tag->at( tag->length() - 2 ) == '/' )
- {
- // All good!
- return;
- }
- else if ( tag->at( tag->length() - 1 ) == '>' )
- {
- // There is more. Could be:
- // text
- // closing tag
- // another node.
- for ( ;; )
- {
- StreamWhiteSpace( in, tag );
-
- // Do we have text?
- if ( in->good() && in->peek() != '<' )
- {
- // Yep, text.
- TiXmlText text( "" );
- text.StreamIn( in, tag );
-
- // What follows text is a closing tag or another node.
- // Go around again and figure it out.
- continue;
- }
-
- // We now have either a closing tag...or another node.
- // We should be at a "<", regardless.
- if ( !in->good() )
- return;
- assert( in->peek() == '<' );
- int tagIndex = tag->length();
-
- bool closingTag = false;
- bool firstCharFound = false;
-
- for( ;; )
- {
- if ( !in->good() )
- return;
-
- int c = in->peek();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
-
- if ( c == '>' )
- break;
-
- *tag += (char) c;
- in->get
- ();
-
- if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
- {
- firstCharFound = true;
- if ( c == '/' )
- closingTag = true;
- }
- }
- // If it was a closing tag, then read in the closing '>' to clean up the input stream.
- // If it was not, the streaming will be done by the tag.
- if ( closingTag )
- {
- if ( !in->good() )
- return;
-
- int c = in->get
- ();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
- assert( c == '>' );
- *tag += (char) c;
-
- // We are done, once we've found our closing tag.
- return;
- }
- else
- {
- // If not a closing tag, id it, and stream.
- const char* tagloc = tag->c_str() + tagIndex;
- TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
- if ( !node )
- return;
- node->StreamIn( in, tag );
- delete node;
- node = 0;
-
- // No return: go around from the beginning: text, closing tag, or node.
- }
- }
- }
+ // We're called with some amount of pre-parsing. That is, some of "this"
+ // element is in "tag". Go ahead and stream to the closing ">"
+ while( in->good() )
+ {
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+ (*tag) += (char) c ;
+
+ if ( c == '>' )
+ break;
+ }
+
+ if ( tag->length() < 3 ) return;
+
+ // Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+ // If not, identify and stream.
+
+ if ( tag->at( tag->length() - 1 ) == '>'
+ && tag->at( tag->length() - 2 ) == '/' )
+ {
+ // All good!
+ return;
+ }
+ else if ( tag->at( tag->length() - 1 ) == '>' )
+ {
+ // There is more. Could be:
+ // text
+ // closing tag
+ // another node.
+ for ( ;; )
+ {
+ StreamWhiteSpace( in, tag );
+
+ // Do we have text?
+ if ( in->good() && in->peek() != '<' )
+ {
+ // Yep, text.
+ TiXmlText text( "" );
+ text.StreamIn( in, tag );
+
+ // What follows text is a closing tag or another node.
+ // Go around again and figure it out.
+ continue;
+ }
+
+ // We now have either a closing tag...or another node.
+ // We should be at a "<", regardless.
+ if ( !in->good() ) return;
+ assert( in->peek() == '<' );
+ int tagIndex = tag->length();
+
+ bool closingTag = false;
+ bool firstCharFound = false;
+
+ for( ;; )
+ {
+ if ( !in->good() )
+ return;
+
+ int c = in->peek();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+
+ if ( c == '>' )
+ break;
+
+ *tag += (char) c;
+ in->get();
+
+ if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+ {
+ firstCharFound = true;
+ if ( c == '/' )
+ closingTag = true;
+ }
+ }
+ // If it was a closing tag, then read in the closing '>' to clean up the input stream.
+ // If it was not, the streaming will be done by the tag.
+ if ( closingTag )
+ {
+ if ( !in->good() )
+ return;
+
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+ assert( c == '>' );
+ *tag += (char) c;
+
+ // We are done, once we've found our closing tag.
+ return;
+ }
+ else
+ {
+ // If not a closing tag, id it, and stream.
+ const char* tagloc = tag->c_str() + tagIndex;
+ TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+ if ( !node )
+ return;
+ node->StreamIn( in, tag );
+ delete node;
+ node = 0;
+
+ // No return: go around from the beginning: text, closing tag, or node.
+ }
+ }
+ }
}
#endif
const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- p = SkipWhiteSpace( p, encoding );
- TiXmlDocument* document = GetDocument();
-
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
- return 0;
- }
-
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, encoding );
- location = data->Cursor();
- }
-
- if ( *p != '<' )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
- return 0;
- }
-
- p = SkipWhiteSpace( p+1, encoding );
-
- // Read the name.
- const char* pErr = p;
-
- p = ReadName( p, &value, encoding );
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
- return 0;
- }
-
- TIXML_STRING endTag ("</");
- endTag += value;
- endTag += ">";
-
- // Check for and read attributes. Also look for an empty
- // tag or an end tag.
- while ( p && *p )
- {
- pErr = p;
- p = SkipWhiteSpace( p, encoding );
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
- return 0;
- }
- if ( *p == '/' )
- {
- ++p;
- // Empty tag.
- if ( *p != '>' )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
- return 0;
- }
- return (p+1);
- }
- else if ( *p == '>' )
- {
- // Done with attributes (if there were any.)
- // Read the value -- which can include other
- // elements -- read the end tag, and return.
- ++p;
- p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens.
- if ( !p || !*p )
- return 0;
-
- // We should find the end tag now
- if ( StringEqual( p, endTag.c_str(), false, encoding ) )
- {
- p += endTag.length();
- return p;
- }
- else
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
- return 0;
- }
- }
- else
- {
- // Try to read an attribute:
- TiXmlAttribute* attrib = new TiXmlAttribute();
- if ( !attrib )
- {
- if ( document )
- document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
- return 0;
- }
-
- attrib->SetDocument( document );
- const char* pErr = p;
- p = attrib->Parse( p, data, encoding );
-
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
- delete attrib;
- return 0;
- }
-
- // Handle the strange case of double attributes:
- TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
- if ( node )
- {
- node->SetValue( attrib->Value() );
- delete attrib;
- return 0;
- }
-
- attributeSet.Add( attrib );
- }
- }
- return p;
+ p = SkipWhiteSpace( p, encoding );
+ TiXmlDocument* document = GetDocument();
+
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+ return 0;
+ }
+
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, encoding );
+ location = data->Cursor();
+ }
+
+ if ( *p != '<' )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+ return 0;
+ }
+
+ p = SkipWhiteSpace( p+1, encoding );
+
+ // Read the name.
+ const char* pErr = p;
+
+ p = ReadName( p, &value, encoding );
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+ return 0;
+ }
+
+ TIXML_STRING endTag ("</");
+ endTag += value;
+ endTag += ">";
+
+ // Check for and read attributes. Also look for an empty
+ // tag or an end tag.
+ while ( p && *p )
+ {
+ pErr = p;
+ p = SkipWhiteSpace( p, encoding );
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+ return 0;
+ }
+ if ( *p == '/' )
+ {
+ ++p;
+ // Empty tag.
+ if ( *p != '>' )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
+ return 0;
+ }
+ return (p+1);
+ }
+ else if ( *p == '>' )
+ {
+ // Done with attributes (if there were any.)
+ // Read the value -- which can include other
+ // elements -- read the end tag, and return.
+ ++p;
+ p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens.
+ if ( !p || !*p )
+ return 0;
+
+ // We should find the end tag now
+ if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+ {
+ p += endTag.length();
+ return p;
+ }
+ else
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+ return 0;
+ }
+ }
+ else
+ {
+ // Try to read an attribute:
+ TiXmlAttribute* attrib = new TiXmlAttribute();
+ if ( !attrib )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+ return 0;
+ }
+
+ attrib->SetDocument( document );
+ const char* pErr = p;
+ p = attrib->Parse( p, data, encoding );
+
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+ delete attrib;
+ return 0;
+ }
+
+ // Handle the strange case of double attributes:
+ TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+ if ( node )
+ {
+ node->SetValue( attrib->Value() );
+ delete attrib;
+ return 0;
+ }
+
+ attributeSet.Add( attrib );
+ }
+ }
+ return p;
}
const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- TiXmlDocument* document = GetDocument();
-
- const char* pWithWhiteSpace = p;
- // Read in text and elements in any order.
- p = SkipWhiteSpace( p, encoding );
- while ( p && *p )
- {
- if ( *p != '<' )
- {
- // Take what we have, make a text element.
- TiXmlText* textNode = new TiXmlText( "" );
-
- if ( !textNode )
- {
- if ( document )
- document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
- return 0;
- }
-
- if ( TiXmlBase::IsWhiteSpaceCondensed() )
- {
- p = textNode->Parse( p, data, encoding );
- }
- else
- {
- // Special case: we want to keep the white space
- // so that leading spaces aren't removed.
- p = textNode->Parse( pWithWhiteSpace, data, encoding );
- }
-
- if ( !textNode->Blank() )
- LinkEndChild( textNode );
- else
- delete textNode;
- }
- else
- {
- // We hit a '<'
- // Have we hit a new element or an end tag?
- if ( StringEqual( p, "</", false, encoding ) )
- {
- return p;
- }
- else
- {
- TiXmlNode* node = Identify( p, encoding );
- if ( node )
- {
- p = node->Parse( p, data, encoding );
- LinkEndChild( node );
- }
- else
- {
- return 0;
- }
- }
- }
- p = SkipWhiteSpace( p, encoding );
- }
-
- if ( !p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
- }
- return p;
+ TiXmlDocument* document = GetDocument();
+
+ const char* pWithWhiteSpace = p;
+ // Read in text and elements in any order.
+ p = SkipWhiteSpace( p, encoding );
+ while ( p && *p )
+ {
+ if ( *p != '<' )
+ {
+ // Take what we have, make a text element.
+ TiXmlText* textNode = new TiXmlText( "" );
+
+ if ( !textNode )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+ return 0;
+ }
+
+ if ( TiXmlBase::IsWhiteSpaceCondensed() )
+ {
+ p = textNode->Parse( p, data, encoding );
+ }
+ else
+ {
+ // Special case: we want to keep the white space
+ // so that leading spaces aren't removed.
+ p = textNode->Parse( pWithWhiteSpace, data, encoding );
+ }
+
+ if ( !textNode->Blank() )
+ LinkEndChild( textNode );
+ else
+ delete textNode;
+ }
+ else
+ {
+ // We hit a '<'
+ // Have we hit a new element or an end tag?
+ if ( StringEqual( p, "</", false, encoding ) )
+ {
+ return p;
+ }
+ else
+ {
+ TiXmlNode* node = Identify( p, encoding );
+ if ( node )
+ {
+ p = node->Parse( p, data, encoding );
+ LinkEndChild( node );
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ p = SkipWhiteSpace( p, encoding );
+ }
+
+ if ( !p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+ }
+ return p;
}
#ifdef TIXML_USE_STL
void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- while ( in->good() )
- {
- int c = in->get
- ();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
- (*tag) += (char) c;
-
- if ( c == '>' )
- {
- // All is well.
- return;
- }
- }
+ while ( in->good() )
+ {
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+ (*tag) += (char) c;
+
+ if ( c == '>' )
+ {
+ // All is well.
+ return;
+ }
+ }
}
#endif
const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- TiXmlDocument* document = GetDocument();
- p = SkipWhiteSpace( p, encoding );
-
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, encoding );
- location = data->Cursor();
- }
- if ( !p || !*p || *p != '<' )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
- return 0;
- }
- ++p;
- value = "";
-
- while ( p && *p && *p != '>' )
- {
- value += *p;
- ++p;
- }
-
- if ( !p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
- }
- if ( *p == '>' )
- return p+1;
- return p;
+ TiXmlDocument* document = GetDocument();
+ p = SkipWhiteSpace( p, encoding );
+
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, encoding );
+ location = data->Cursor();
+ }
+ if ( !p || !*p || *p != '<' )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+ return 0;
+ }
+ ++p;
+ value = "";
+
+ while ( p && *p && *p != '>' )
+ {
+ value += *p;
+ ++p;
+ }
+
+ if ( !p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+ }
+ if ( *p == '>' )
+ return p+1;
+ return p;
}
#ifdef TIXML_USE_STL
void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- while ( in->good() )
- {
- int c = in->get
- ();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
-
- (*tag) += (char) c;
-
- if ( c == '>'
- && tag->at( tag->length() - 2 ) == '-'
- && tag->at( tag->length() - 3 ) == '-' )
- {
- // All is well.
- return;
- }
- }
+ while ( in->good() )
+ {
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+
+ (*tag) += (char) c;
+
+ if ( c == '>'
+ && tag->at( tag->length() - 2 ) == '-'
+ && tag->at( tag->length() - 3 ) == '-' )
+ {
+ // All is well.
+ return;
+ }
+ }
}
#endif
const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- TiXmlDocument* document = GetDocument();
- value = "";
-
- p = SkipWhiteSpace( p, encoding );
-
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, encoding );
- location = data->Cursor();
- }
- const char* startTag = "<!--";
- const char* endTag = "-->";
-
- if ( !StringEqual( p, startTag, false, encoding ) )
- {
- document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
- return 0;
- }
- p += strlen( startTag );
- p = ReadText( p, &value, false, endTag, false, encoding );
- return p;
+ TiXmlDocument* document = GetDocument();
+ value = "";
+
+ p = SkipWhiteSpace( p, encoding );
+
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, encoding );
+ location = data->Cursor();
+ }
+ const char* startTag = "<!--";
+ const char* endTag = "-->";
+
+ if ( !StringEqual( p, startTag, false, encoding ) )
+ {
+ document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+ return 0;
+ }
+ p += strlen( startTag );
+ p = ReadText( p, &value, false, endTag, false, encoding );
+ return p;
}
const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- p = SkipWhiteSpace( p, encoding );
- if ( !p || !*p )
- return 0;
-
- int tabsize = 4;
- if ( document )
- tabsize = document->TabSize();
-
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, encoding );
- location = data->Cursor();
- }
- // Read the name, the '=' and the value.
- const char* pErr = p;
- p = ReadName( p, &name, encoding );
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
- return 0;
- }
- p = SkipWhiteSpace( p, encoding );
- if ( !p || !*p || *p != '=' )
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
- return 0;
- }
-
- ++p; // skip '='
- p = SkipWhiteSpace( p, encoding );
- if ( !p || !*p )
- {
- if ( document )
- document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
- return 0;
- }
-
- const char* end;
-
- if ( *p == '\'' )
- {
- ++p;
- end = "\'";
- p = ReadText( p, &value, false, end, false, encoding );
- }
- else if ( *p == '"' )
- {
- ++p;
- end = "\"";
- p = ReadText( p, &value, false, end, false, encoding );
- }
- else
- {
- // All attribute values should be in single or double quotes.
- // But this is such a common error that the parser will try
- // its best, even without them.
- value = "";
- while ( p && *p // existence
- && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace
- && *p != '/' && *p != '>' ) // tag end
- {
- value += *p;
- ++p;
- }
- }
- return p;
+ p = SkipWhiteSpace( p, encoding );
+ if ( !p || !*p ) return 0;
+
+ int tabsize = 4;
+ if ( document )
+ tabsize = document->TabSize();
+
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, encoding );
+ location = data->Cursor();
+ }
+ // Read the name, the '=' and the value.
+ const char* pErr = p;
+ p = ReadName( p, &name, encoding );
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+ return 0;
+ }
+ p = SkipWhiteSpace( p, encoding );
+ if ( !p || !*p || *p != '=' )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+ return 0;
+ }
+
+ ++p; // skip '='
+ p = SkipWhiteSpace( p, encoding );
+ if ( !p || !*p )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+ return 0;
+ }
+
+ const char* end;
+
+ if ( *p == '\'' )
+ {
+ ++p;
+ end = "\'";
+ p = ReadText( p, &value, false, end, false, encoding );
+ }
+ else if ( *p == '"' )
+ {
+ ++p;
+ end = "\"";
+ p = ReadText( p, &value, false, end, false, encoding );
+ }
+ else
+ {
+ // All attribute values should be in single or double quotes.
+ // But this is such a common error that the parser will try
+ // its best, even without them.
+ value = "";
+ while ( p && *p // existence
+ && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace
+ && *p != '/' && *p != '>' ) // tag end
+ {
+ value += *p;
+ ++p;
+ }
+ }
+ return p;
}
#ifdef TIXML_USE_STL
void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- while ( in->good() )
- {
- int c = in->peek();
- if ( c == '<' )
- return;
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
-
- (*tag) += (char) c;
- in->get
- ();
- }
+ while ( in->good() )
+ {
+ int c = in->peek();
+ if ( c == '<' )
+ return;
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+
+ (*tag) += (char) c;
+ in->get();
+ }
}
#endif
const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
- value = "";
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, encoding );
- location = data->Cursor();
- }
- bool ignoreWhite = true;
-
- const char* end = "<";
- p = ReadText( p, &value, ignoreWhite, end, false, encoding );
- if ( p )
- return p-1; // don't truncate the '<'
- return 0;
+ value = "";
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, encoding );
+ location = data->Cursor();
+ }
+ bool ignoreWhite = true;
+
+ const char* end = "<";
+ p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+ if ( p )
+ return p-1; // don't truncate the '<'
+ return 0;
}
#ifdef TIXML_USE_STL
void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
{
- while ( in->good() )
- {
- int c = in->get
- ();
- if ( c <= 0 )
- {
- TiXmlDocument* document = GetDocument();
- if ( document )
- document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
- return;
- }
- (*tag) += (char) c;
-
- if ( c == '>' )
- {
- // All is well.
- return;
- }
- }
+ while ( in->good() )
+ {
+ int c = in->get();
+ if ( c <= 0 )
+ {
+ TiXmlDocument* document = GetDocument();
+ if ( document )
+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+ return;
+ }
+ (*tag) += (char) c;
+
+ if ( c == '>' )
+ {
+ // All is well.
+ return;
+ }
+ }
}
#endif
const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
{
- p = SkipWhiteSpace( p, _encoding );
- // Find the beginning, find the end, and look for
- // the stuff in-between.
- TiXmlDocument* document = GetDocument();
- if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
- {
- if ( document )
- document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
- return 0;
- }
- // TiXmlParsingData data( p, prevData );
- if ( data )
- {
- data->Stamp( p, _encoding );
- location = data->Cursor();
- }
- p += 5;
-
- version = "";
- encoding = "";
- standalone = "";
-
- while ( p && *p )
- {
- if ( *p == '>' )
- {
- ++p;
- return p;
- }
-
- p = SkipWhiteSpace( p, _encoding );
- if ( StringEqual( p, "version", true, _encoding ) )
- {
- TiXmlAttribute attrib;
- p = attrib.Parse( p, data, _encoding );
- version = attrib.Value();
- }
- else if ( StringEqual( p, "encoding", true, _encoding ) )
- {
- TiXmlAttribute attrib;
- p = attrib.Parse( p, data, _encoding );
- encoding = attrib.Value();
- }
- else if ( StringEqual( p, "standalone", true, _encoding ) )
- {
- TiXmlAttribute attrib;
- p = attrib.Parse( p, data, _encoding );
- standalone = attrib.Value();
- }
- else
- {
- // Read over whatever it is.
- while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
- ++p;
- }
- }
- return 0;
+ p = SkipWhiteSpace( p, _encoding );
+ // Find the beginning, find the end, and look for
+ // the stuff in-between.
+ TiXmlDocument* document = GetDocument();
+ if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+ {
+ if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+ return 0;
+ }
+// TiXmlParsingData data( p, prevData );
+ if ( data )
+ {
+ data->Stamp( p, _encoding );
+ location = data->Cursor();
+ }
+ p += 5;
+
+ version = "";
+ encoding = "";
+ standalone = "";
+
+ while ( p && *p )
+ {
+ if ( *p == '>' )
+ {
+ ++p;
+ return p;
+ }
+
+ p = SkipWhiteSpace( p, _encoding );
+ if ( StringEqual( p, "version", true, _encoding ) )
+ {
+ TiXmlAttribute attrib;
+ p = attrib.Parse( p, data, _encoding );
+ version = attrib.Value();
+ }
+ else if ( StringEqual( p, "encoding", true, _encoding ) )
+ {
+ TiXmlAttribute attrib;
+ p = attrib.Parse( p, data, _encoding );
+ encoding = attrib.Value();
+ }
+ else if ( StringEqual( p, "standalone", true, _encoding ) )
+ {
+ TiXmlAttribute attrib;
+ p = attrib.Parse( p, data, _encoding );
+ standalone = attrib.Value();
+ }
+ else
+ {
+ // Read over whatever it is.
+ while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+ ++p;
+ }
+ }
+ return 0;
}
bool TiXmlText::Blank() const
{
- for ( unsigned i=0; i<value.length(); i++ )
- if ( !IsWhiteSpace( value[i] ) )
- return false;
- return true;
+ for ( unsigned i=0; i<value.length(); i++ )
+ if ( !IsWhiteSpace( value[i] ) )
+ return false;
+ return true;
}
diff --git a/src/glob.h b/src/glob.h
index 75f356e..c134df5 100755
--- a/src/glob.h
+++ b/src/glob.h
@@ -5,7 +5,8 @@
gmake config in the main directory!
*/
-#include "maps/hashmap.h"
+
+#include <map>
// global variables.
#ifndef GLOB_H
@@ -18,36 +19,18 @@
/* - CONFIG -
What should be the name of the config file?
*/
-#define CONFILE "ychat.conf"
+#define CONFILE "yhttpd.conf"
/* - CONFIG -
- In which prefix should yChat be installed if typing gmake inst-
+ In which prefix should yhttpd be installed if typing gmake inst-
all?
*/
#define PREFIX "/usr/local"
-//<<*
-/* - CONFIG -
- Should yChat get compiled with database support? Currently MyS-
- QL only is a supported database.
-*/
-//#define DATABASE
-
-#ifdef DATABASE
-/* - CONFIG -
- Should all database queries printed out at the admin interface?
- (This option wont take action if database support has not been
- chosen)
-*/
-#define DATA_PRINT_QUERIES
-
-#define USE_MYSQL
-#endif
-//*>>
/* - CONFIG -
Please enter the highest networking port which is allowed to be
- used. If yChat is unable to create the server socket on a cert-
+ used. If yhttpd is unable to create the server socket on a cert-
ain port, it will increment the port number and retries to cre-
ate another socket on the incremented port number. This proced-
ure will continue until MAXPORT has been reached.
@@ -64,7 +47,7 @@
Please specify the size of a temporary buffer. (Will be used f-
or different tasks)
*/
-#define READBUF 2048
+#define READBUF 1024
/* - CONFIG -
Please specify the maximum length of a HTTP post request.
@@ -80,32 +63,27 @@
/* - CONFIG -
Please chose if you want to use verbose server outputs or not.
The verbose messages will appear in the ncurses menu if ncurses
- is enabled or in the server-window if yChat has been compiled
+ is enabled or in the server-window if yhttpd has been compiled
without ncurses support. This option shows you all incoming
requests with the client IP and port numbers. You probably want
- this to be turned off if you have heavy server load.
+ this to be turned of if you have heavy server load.
*/
//#define VERBOSE
/* - CONFIG -
If you want to enable EXPERIMENTAL features, then set this val-
ue to true. Else use false which is recommended! All experimen-
- al features are marked inside of the running yChat!
+ al features are marked inside of the running yhttpd!
*/
//#define EXPERIM
/* - CONFIG -
- Should yChat get compiled with logging support?
-*/
-#define LOGGING
-
-/* - CONFIG -
- Should yChat get compiled with ncurses support?
+ Should yhttpd get compiled with ncurses support?
*/
#define NCURSES
/* - CONFIG -
- Should yChat get compiled with comand line interface support?
+ Should yhttpd get compiled with comand line interface support?
*/
#define CLI
@@ -121,14 +99,6 @@
// Enables debugging options
//#define DEBUG
-//<<*
-/* - CONFIG -
- Defines the amount of newlines which have to be sent to the clie-
- nt's chat stream after the first log-in. It prevents a white scr-
- een because of browser buffers or proxies.
-*/
-#define PUSHSTR 500
-//*>>
// The following values define the positions of the data stats in the NCURSES interface.
@@ -154,8 +124,8 @@
#define NCUR_CON_QUEUE_X 23
#define NCUR_CON_QUEUE_Y 35
-#define NCUR_CHAT_HEADER_X 21
-#define NCUR_CHAT_HEADER_Y 52
+#define NCUR_HTTPD_HEADER_X 21
+#define NCUR_HTTPD_HEADER_Y 52
#define NCUR_NUM_ROOMS_X 22
#define NCUR_NUM_ROOMS_Y 52
#define NCUR_SESSION_X 23
@@ -183,6 +153,8 @@
using namespace std;
+// some custom typedefs for datatypes which are needed often.
+typedef map<string, string> map_string;
typedef int function( void *v_arg );
struct container
diff --git a/src/html.cpp b/src/html.cpp
index e9b4bf7..7f1440d 100755
--- a/src/html.cpp
+++ b/src/html.cpp
@@ -6,144 +6,123 @@
using namespace std;
-html::html( )
+html::html( ) : smap<string,string>::smap(HMAPOCC)
{
- set_name( wrap::CONF->get_elem( "httpd.templatedir" ) );
+ set_name( wrap::CONF->get_elem( "httpd.templatedir" ) );
}
html::~html( )
-{}
+{
+}
void
html::clear_cache( )
{
- clear();
- wrap::system_message( CLRHTML );
-
-#ifdef NCURSES
+ make_empty();
+ wrap::system_message( CLRHTML );
- print_cached( 0 );
+#ifdef NCURSES
+ print_cached( 0 );
#endif
}
string
-html::parse( hashmap<string> &map_params )
+html::parse( map_string &map_params )
{
- string s_file = map_params["request"];
-
- // check if s_file is in the container.
- string s_templ;
+ string s_file = map_params["request"];
- // if not, read file.
- if ( ! shashmap<string>::exists( s_file ) )
- {
- string s_path = get_name();
- ifstream if_templ( s_path.append( s_file ).c_str(), ios::binary );
+ // check if s_file is in the container.
+ string s_templ;
- if ( ! if_templ )
+ // if not, read file.
+ if ( ! smap<string,string>::is_avail( s_file ) )
{
- wrap::system_message( OFFFOUND + s_path );
- if(map_params["request"]== wrap::CONF->get_elem( "httpd.html.notfound" ))
- return "";
+ auto string s_path = get_name();
+ auto ifstream fs_templ( s_path.append( s_file ).c_str(), ios::binary );
- map_params["request"] = wrap::CONF->get_elem( "httpd.html.notfound" );
- return parse( map_params );
+ if ( ! fs_templ )
+ {
+ wrap::system_message( OFFFOUND + s_path );
+ if(map_params["request"]== wrap::CONF->get_elem( "httpd.html.notfound" ))
+ return "";
- }
+ map_params["request"] = wrap::CONF->get_elem( "httpd.html.notfound" );
+ return parse( map_params );
- char c_buf;
- while( !if_templ.eof() )
- {
- if_templ.get( c_buf );
- s_templ += c_buf;
- }
+ }
- if ( map_params["content-type"].compare(0,5,"text/") == 0 )
- s_templ.erase(s_templ.end()-1);
+ auto char c_buf;
+ while( !fs_templ.eof() )
+ {
+ fs_templ.get( c_buf );
+ s_templ+=c_buf;
+ }
- if_templ.close();
+ fs_templ.close();
- wrap::system_message( TECACHE + s_path );
+ wrap::system_message( TECACHE + s_path );
- // cache file.
- shashmap<string>::add_elem(s_templ, s_file);
-#ifdef NCURSES
-
- print_cached( shashmap<string>::size() );
+ // cache file.
+ smap<string,string>::add_elem( s_templ, s_file );
+#ifdef NCURSES
+ print_cached( smap<string,string>::get_size() );
#endif
+ }
- }
- else
- {
- s_templ = shashmap<string>::get_elem( s_file );
- }
-
- // find %%KEY%% token and substituate those.
- unsigned pos[2];
- pos[0] = pos[1] = 0;
+ else
+ {
+ s_templ = smap<string,string>::get_elem( s_file );
+ }
- for(;;)
- {
- pos[0] = s_templ.find( "%%", pos[1] );
+ // find %%KEY%% token and substituate those.
+ auto unsigned int pos[2];
+ pos[0] = pos[1] = 0;
- if ( pos[0] == string::npos )
- break;
+ for(;;)
+ {
+ pos[0] = s_templ.find( "%%", pos[1] );
- pos[0] += 2;
- pos[1] = s_templ.find( "%%", pos[0] );
+ if ( pos[0] == string::npos )
+ break;
- if ( pos[0] == string::npos )
- break;
+ pos[0] += 2;
+ pos[1] = s_templ.find( "%%", pos[0] );
- // get key and val.
- string s_key = s_templ.substr( pos[0], pos[1]-pos[0] );
- string s_val = wrap::CONF->get_elem( s_key );
+ if ( pos[0] == string::npos )
+ break;
- // if s_val is empty use map_params.
- if ( s_val.empty() )
- s_val = map_params[ s_key ];
+ // get key and val.
+ auto string s_key = s_templ.substr( pos[0], pos[1]-pos[0] );
+ auto string s_val = wrap::CONF->get_elem( s_key );
- // substituate key with val.
- s_templ.replace( pos[0]-2, pos[1]-pos[0]+4, s_val );
+ // if s_val is empty use map_params.
+ if ( s_val.empty() )
+ s_val = map_params[ s_key ];
+
+ // substituate key with val.
+ s_templ.replace( pos[0]-2, pos[1]-pos[0]+4, s_val );
- // calculate the string displacement.
- int i_diff = s_val.length() - ( pos[1] - pos[0] + 4);
+ // calculate the string displacement.
+ auto int i_dif = s_val.length() - ( pos[1] - pos[0] + 4);
- pos[1] += 2 + i_diff;
+ pos[1] += 2 + i_dif;
- };
+ };
- return s_templ;
+ return s_templ;
}
-//<<*
-void
-html::online_list( user *p_user, hashmap<string> &map_params )
-{
- // prepare user_list.
- string s_list;
-
- room* p_room = p_user->get_room();
-
- p_room->get_user_list( s_list );
-
- map_params["ROOMNAME"] = p_room->get_name();
- map_params["ROOMTOPIC"] = p_room->get_topic();
- map_params["USERLIST"] = s_list;
-}
-//*>>
#ifdef NCURSES
void
html::print_cached( int i_docs )
{
- if ( !wrap::NCUR->is_ready() )
- return;
+ if ( !wrap::NCUR->is_ready() )
+ return;
- mvprintw( NCUR_CACHED_DOCS_X, NCUR_CACHED_DOCS_Y, "Docs: %d ", i_docs);
- refresh();
+ mvprintw( NCUR_CACHED_DOCS_X, NCUR_CACHED_DOCS_Y, "Docs: %d ", i_docs);
+ refresh();
}
-
#endif
#endif
diff --git a/src/html.h b/src/html.h
index 209371f..d8d2a16 100755
--- a/src/html.h
+++ b/src/html.h
@@ -4,37 +4,36 @@
#ifndef HTML_H
#define HTML_H
-#include "maps/shashmap.h"
-#include "chat/user.h"
+#include "maps/smap.h"
#include "name.h"
using namespace std;
-class html : public shashmap<string>, name
+class html : public smap<string, string>, name
{
+private:
+
public:
- html( );
- ~html( );
-
- // Clears the template cache so that new html templates will be read
- // from hard disk. This method is needed after changeing s.t. on
- // the html-template files.
- void clear_cache( );
-
- // Returns a parsed html-template. this method will check first if the
- // required html-template exists inside the classes template cache. if not
- // then the file will be read from file and added to the cache.
- // afterwards the html-template will be parsed and returned.
- // map_params contains the client request parameters which also will be
- // used for string substituation.
- string parse( hashmap<string> &map_params );
-
- void online_list( user *p_user, hashmap<string> &map_params ); //<<
-#ifdef NCURSES
+ // public methods.
+ html( ); // simple constructor.
+ ~html( );
+
+ // clears the template cache so that new html templates will be read
+ // from hard disk. this method is needed after changeing s.t. on
+ // the html-template files.
+ void clear_cache( );
+
+ // returns a parsed html-template. this method will check first if the
+ // required html-template exists inside the classes template cache. if not
+ // then the file will be read from file and added to the cache.
+ // afterwards the html-template will be parsed and returned.
+ // map_params contains the client request parameters which also will be
+ // used for string substituation.
+ string parse( map_string &map_params );
- void print_cached( int i_docs );
+#ifdef NCURSES
+ void print_cached( int i_docs );
#endif
-
};
#endif
diff --git a/src/incl.h b/src/incl.h
index 115478d..d62a57f 100755
--- a/src/incl.h
+++ b/src/incl.h
@@ -1,13 +1,9 @@
-#include <pthread.h>
#include <iostream>
+#include <pthread.h>
#include <string>
-//#include <map>
-
#include "glob.h"
-
#ifdef NCURSES
#include <ncurses.h>
#endif
-
#include "msgs.h"
#include "wrap.h"
diff --git a/src/logd.cpp b/src/logd.cpp
index b572a42..44c42e2 100755
--- a/src/logd.cpp
+++ b/src/logd.cpp
@@ -1,171 +1,157 @@
-
#ifndef LOGD_CPP
#define LOGD_CPP
-#include "logd.h"
-
-#ifdef LOGGING
-
#include <fstream>
+#include "logd.h"
logd::logd( string s_filename, string s_log_lines )
{
- initialize( s_filename, tool::string2int(s_log_lines) );
+ initialize( s_filename, tool::string2int(s_log_lines) );
}
logd::logd( string s_filename, int i_log_lines )
{
- initialize( s_filename, i_log_lines );
+ initialize( s_filename, i_log_lines );
}
logd::~logd()
{
- flush_logs();
- pthread_mutex_destroy( &mut_s_logging );
+ flush();
+ pthread_mutex_destroy( &mut_s_logging );
}
void
logd::initialize( string s_filename, int i_log_lines )
{
- pthread_mutex_init( &mut_s_logging, NULL );
+ pthread_mutex_init( &mut_s_logging, NULL );
- if( s_filename.empty() )
- {
- wrap::system_message( LOGERR2 );
- exit(1);
- }
+ if( s_filename.empty() )
+ {
+ wrap::system_message( LOGERR2 );
+ exit(1);
+ }
- s_logfile = s_filename;
- i_lines = i_log_lines;
+ s_logfile = s_filename;
+ i_lines = i_log_lines;
}
string
logd::get_time_string()
{
- struct tm *t_m;
- time_t t_cur = time(NULL);
- t_m = gmtime(&t_cur);
+ struct tm *t_m;
+ time_t t_cur = time(NULL);
+ t_m = gmtime(&t_cur);
- char c_buf[100];
- c_buf[99] = '\0';
- strftime(c_buf, 100, "[%d/%b/%Y:%H:%M:%S %z]", t_m);
+ char c_buf[100];
+ c_buf[99] = '\0';
+ strftime(c_buf, 100, "[%d/%b/%Y:%H:%M:%S %z]", t_m);
- return string(c_buf);
+ return string(c_buf);
}
-void
+void
logd::flush()
{
- ofstream of_output;
+ ofstream of_output;
- of_output.open(s_logfile.c_str(), ios::app);
+ of_output.open(s_logfile.c_str(), ios::app);
- if( of_output == NULL )
- {
- wrap::system_message( LOGERR1 + s_logfile );
- exit(1);
- }
+ if( of_output == NULL )
+ {
+ wrap::system_message( LOGERR1 + s_logfile );
+ exit(1);
+ }
- while( ! s_queue.empty() )
- {
- string s_l=s_queue.front();
- s_queue.pop();
- of_output.write( s_l.c_str(), s_l.size() );
- }
+ while( ! s_queue.empty() )
+ {
+ string s_l=s_queue.front();
+ s_queue.pop();
+ of_output.write( s_l.c_str(), s_l.size() );
+ }
- of_output.close();
+ of_output.close();
}
void
-logd::log_access( hashmap<string> &map_request )
+logd::log_access( map_string request )
{
- string s_time = get_time_string();
- string s_logstr = map_request["REMOTE_ADDR"] + " - - "+s_time+" \"" + map_request["QUERY_STRING"]+"\" 200 0 \""+map_request["request"]+"\" \""+map_request["User-Agent"]+"\"\n";
-
- pthread_mutex_lock ( &mut_s_logging );
- s_queue.push(s_logstr);
-
- if ( s_queue.size() > i_lines )
- flush();
-
- pthread_mutex_unlock( &mut_s_logging );
+ string s_time = get_time_string();
+ string s_logstr = request["REMOTE_ADDR"] + " - - "+s_time+" \"" + request["QUERY_STRING"]+"\" 200 0 \""+request["request"]+"\" \""+request["User-Agent"]+"\"\n";
+
+ pthread_mutex_lock ( &mut_s_logging );
+ s_queue.push(s_logstr);
+ if ( s_queue.size() > i_lines )
+ flush();
+ pthread_mutex_unlock( &mut_s_logging );
}
void
logd::log_simple_line( string s_line )
{
- // Dont log empty lines!
- if (s_line.empty())
- return;
-
- string s_time = get_time_string();
- string s_logstr = s_time + " " + s_line;
-
- pthread_mutex_lock ( &mut_s_logging );
- s_queue.push(s_logstr);
-
- if ( s_queue.size() > i_lines )
- flush();
-
- pthread_mutex_unlock( &mut_s_logging );
+ string s_time = get_time_string();
+ string s_logstr = s_time + " " + s_line;
+
+ pthread_mutex_lock ( &mut_s_logging );
+ s_queue.push(s_logstr);
+ if ( s_queue.size() > i_lines )
+ flush();
+ pthread_mutex_unlock( &mut_s_logging );
}
void
logd::set_logfile( string s_path, string s_filename )
{
- // Remove "/" from filename!
- unsigned i_pos = s_filename.find( "/" );
- while ( i_pos != string::npos )
- {
- s_filename.replace( i_pos, 1, "SLASH" );
- i_pos = s_filename.find( "/" );
- }
-
- // Remove "\" from filename (for non unix systems)!
- i_pos = s_filename.find( "\\" );
- while ( i_pos != string::npos )
- {
- s_filename.replace( i_pos, 1, "BACKSLASH" );
+ // Remove "/" from filename!
+ unsigned int i_pos = s_filename.find( "/" );
+ while ( i_pos != string::npos )
+ {
+ s_filename.replace( i_pos, 1, "SLASH" );
+ i_pos = s_filename.find( "/" );
+ }
+
+ // Remove "\" from filename (for non unix systems)!
i_pos = s_filename.find( "\\" );
- }
-
- pthread_mutex_lock ( &mut_s_logging );
- this->s_logfile = s_path + s_filename;
- pthread_mutex_unlock( &mut_s_logging );
+ while ( i_pos != string::npos )
+ {
+ s_filename.replace( i_pos, 1, "BACKSLASH" );
+ i_pos = s_filename.find( "\\" );
+ }
+
+ pthread_mutex_lock ( &mut_s_logging );
+ this->s_logfile = s_path + s_filename;
+ pthread_mutex_unlock( &mut_s_logging );
}
void
logd::flush_logs()
{
- pthread_mutex_lock ( &mut_s_logging );
- flush();
- pthread_mutex_unlock( &mut_s_logging );
+ pthread_mutex_lock ( &mut_s_logging );
+ flush();
+ pthread_mutex_unlock( &mut_s_logging );
}
string
logd::remove_html_tags( string s_logs )
{
- unsigned pos[2];
+ unsigned pos[2];
- while ( (pos[0] = s_logs.find("<")) != string::npos )
- {
- if ( (pos[1] = s_logs.find(">", pos[0])) != string::npos )
- s_logs.replace( pos[0], pos[1]-pos[0]+1, "");
- else
+ while ( (pos[0] = s_logs.find("<")) != string::npos )
+ {
+ if ( (pos[1] = s_logs.find(">", pos[0])) != string::npos )
+ s_logs.replace( pos[0], pos[1]-pos[0]+1, "");
+ else
break;
- }
+ }
- if ( s_logs == "\n" )
- return "";
+ if ( s_logs == "\n" )
+ return "";
- return s_logs;
+ return s_logs;
}
void
logd::set_lines( const int i_lines )
{
- this->i_lines = i_lines;
+ this->i_lines = i_lines;
}
-
-#endif
#endif
diff --git a/src/logd.h b/src/logd.h
index 4796e39..b91efe0 100755
--- a/src/logd.h
+++ b/src/logd.h
@@ -1,39 +1,36 @@
#include "incl.h"
-#ifdef LOGGING
#ifndef LOGD_H
#define LOGD_H
#include <queue>
#include <time.h>
-#include "maps/hashmap.h"
-
class logd
{
+
private:
- string s_logfile;
- queue<string> s_queue;
- pthread_mutex_t mut_s_logging;
- int i_lines;
+ string s_logfile;
+ queue<string> s_queue;
+ pthread_mutex_t mut_s_logging;
+ int i_lines;
- void initialize( string s_filename, int i_log_lines );
- void flush();
- void set_lines( const int i_lines );
- string get_time_string();
+ void initialize( string s_filename, int i_log_lines );
+ void flush();
+ void set_lines( const int i_lines );
+ string get_time_string();
public:
- logd( string s_filename, string s_log_lines );
- logd( string s_filename, int i_log_lines );
- ~logd();
-
- void set_logfile( string s_path, string s_filename );
- void log_access( hashmap<string> &map_request );
- void log_simple_line( string s_line );
- void flush_logs();
- static string remove_html_tags( string s_log );
+ logd( string s_filename, string s_log_lines );
+ logd( string s_filename, int i_log_lines );
+ ~logd();
+
+ void set_logfile( string s_path, string s_filename );
+ void log_access( map_string request );
+ void log_simple_line( string s_line );
+ void flush_logs();
+ static string remove_html_tags( string s_log );
};
-#endif
-#endif
+#endif
diff --git a/src/main.cpp b/src/main.cpp
index 3470148..0948e63 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,7 @@
/*
- * yChat; Contact: www.yChat.org; Mail@yChat.org
+ * yhttpd++; Contact: www.yhttpd.org; Mail@yhttpd.org
* Copyright (C) 2003 Paul C. Buetow, Volker Richter
- * Copyright (C) 2004, 2005 Paul C. Buetow
+ * Copyright (C) 2004 Paul C. Buetow
* -----------------------------------------------------------------
*
* This program is free software; you can redistribute it and/or
@@ -30,161 +30,130 @@
#endif
#endif
-#include "maps/hashmap.h"
-
using namespace std;
map<string,string>*
parse_argc( int argc, char* argv[] )
{
- map<string,string>* start_params = new map<string,string>;
+ map<string,string>* start_params = new map<string,string>;
+
+ string s_output = "";
- string s_output = "";
+ // Set to 1 if a config option key has to be read ( ./yhttpd -o key1 value1 -o key2 value2 ... );
+ bool b_conf = 0;
- // Set to 1 if a config option key has to be read
- // ( ./ychat -o key1 value1 -o key2 value2 ... );
- bool b_conf = 0;
+ // Will store the key of an additional option value (see also b_conf)
+ string s_key;
- // Will store the key of an additional option value (see also b_conf)
- string s_key;
+ for (int i=1; argv[i] != 0; i++)
+ {
- for (int i=1; argv[i] != 0; i++)
+ if ( !s_key.empty() )
+ {
+ (*start_params)[s_key] = string(argv[i]);
+ s_key.clear();
+ }
+ else if ( b_conf )
{
- if ( !s_key.empty() )
- {
- (*start_params)[s_key] = string(argv[i]);
- s_key.clear();
- }
- else if ( b_conf )
- {
- s_key = string(argv[i]);
- b_conf = 0;
- }
- else
- {
- if ( string(argv[i]).find("v") != string::npos )
- s_output.append(tool::ychat_version()+"\n");
-
- if ( string(argv[i]).find("h") != string::npos )
- s_output.append( YCUSAGE );
-
- if ( string(argv[i]).find("o") != string::npos )
- b_conf = 1;
- }
+ s_key = string(argv[i]);
+ b_conf = 0;
}
- if ( !s_output.empty() )
+ else
{
- cout << s_output;
- delete start_params;
- exit(1);
+ if ( string(argv[i]).find("v") != string::npos )
+ s_output.append(tool::yhttpd_version()+"\n");
+ if ( string(argv[i]).find("h") != string::npos )
+ s_output.append( "Usage: ./yhttpd {h|v}|{o confkey confvalue}\n" );
+ if ( string(argv[i]).find("o") != string::npos )
+ b_conf = 1;
}
+ }
- return start_params;
+ if ( s_output.compare("") != 0 )
+ {
+ cout << s_output;
+ delete start_params;
+ exit(0);
+ }
+
+ return start_params;
}
int
main(int argc, char* argv[])
{
- map<string,string>* p_start_params = parse_argc( argc, argv );
+ map<string,string>* p_start_params = parse_argc( argc, argv );
- cout << tool::ychat_version() << endl
- << DESCRIP << endl
- << DESCRI2 << endl
- << CONTACT << endl
- << SEPERAT << endl;
+ cout << tool::yhttpd_version() << endl
+ << DESCRIP << endl
+ << DESCRI2 << endl
+ << CONTACT << endl
+ << SEPERAT << endl;
- // Ignore SIGPIPE. otherwise the server will shut down with "Broken pipe" if
- // a client unexpected disconnects himself from a SOCK_STREAM.
- signal( SIGPIPE, SIG_IGN );
+ // ignore SIGPIPE. otherwise the server will shut down with "Broken pipe" if
+ // a client unexpected disconnects himself from a SOCK_STREAM.
+ signal( SIGPIPE, SIG_IGN );
- // All the static data classes have to be initialized once. otherwise they will
- // contain only empty pointers and the chat server won't work correctly.
- // the order of the initializations is very importand. for example the s_html::init()
- // invokations assumes an initialized conf class.
+ // all the static data classes have to be initialized once. otherwise they will
+ // contain only empty pointers and the chat server won't work correctly.
+ // the order of the initializations is very importand. for example the s_html::init()
+ // invokations assumes an initialized s_conf class.
+ // begin to draw the ncurses amdin interface in a new pthread.
- // Init the dynamic wrapper (is needed to pass all wrapped objects through a single pointer).
- wrap::WRAP = new dynamic_wrap;
+ // init the dynamic wrapper (is needed to pass all wrapped objects through a single pointer).
+ wrap::WRAP = new dynamic_wrap;
- // Init the config manager.
- wrap::WRAP->CONF = wrap::CONF = new conf( CONFILE, p_start_params );
- delete p_start_params,
+ // init the config manager.
+ wrap::WRAP->CONF = wrap::CONF = new conf( CONFILE, p_start_params );
+ delete p_start_params,
- // Init the statistic manager.
- wrap::WRAP->STAT = wrap::STAT = new stats;
- // Init the html-template manager.
- wrap::WRAP->HTML = wrap::HTML = new html;
+ // init the statistic manager.
+ wrap::WRAP->STAT = wrap::STAT = new stats;
-#ifdef LOGGING
- // Init the system message logd
- wrap::WRAP->LOGD = wrap::LOGD = new logd( wrap::CONF->get_elem("httpd.logging.systemfile"),
- wrap::CONF->get_elem("httpd.logging.systemlines") );
-#endif
- //<<*
- // Init the session manager.
- wrap::WRAP->SMAN = wrap::SMAN = new sman;
- //*>>
+ // init the html-template manager.
+ wrap::WRAP->HTML = wrap::HTML = new html;
+ // init the system message logd
+ wrap::WRAP->LOGD = wrap::LOGD = new logd( wrap::CONF->get_elem("httpd.logging.systemfile"),
+ wrap::CONF->get_elem("httpd.logging.systemlines") );
+
- // Init the socket manager.
- wrap::WRAP->SOCK = wrap::SOCK = new sock;
+ // init the socket manager.
+ wrap::WRAP->SOCK = wrap::SOCK = new sock;
#ifdef NCURSES
+ wrap::WRAP->NCUR = wrap::NCUR = new ncur; // init the ncurses admin interface.
+ wrap::NCUR->run(); // run the thread
- wrap::WRAP->NCUR = wrap::NCUR = new ncur; // init the ncurses admin interface.
- wrap::NCUR->run(); // run the thread
-
- // Wait until ncurses interface has been initialized.
- while ( ! wrap::NCUR->is_ready() )
- usleep(1000);
-
- wrap::HTML->print_cached(0);
+ // wait until ncurses interface has been initialized.
+ while ( ! wrap::NCUR->is_ready() )
+ usleep(1000);
#endif
- //<<*
- // Init the chat manager.
- wrap::WRAP->CHAT = wrap::CHAT = new chat;
- //*>>
-
- // Init the system timer.
- wrap::WRAP->TIMR = wrap::TIMR = new timr;
- wrap::TIMR->run(); // run the thread
-
- //<<*
- // Init the module-loader manager.
- wrap::WRAP->MODL = wrap::MODL = new modl;
- // Init the garbage collector
- wrap::WRAP->GCOL = wrap::GCOL = new gcol;
+ // init the system timer.
+ wrap::WRAP->TIMR = wrap::TIMR = new timr;
+ wrap::TIMR->run(); // run the thread
- // Init the data manager.
-#ifdef DATABASE
+ // init the module-loader manager.
+ wrap::WRAP->MODL = wrap::MODL = new modl;
- wrap::WRAP->DATA = wrap::DATA = new data;
-#endif
- //*>>
#ifndef NCURSES
#ifdef CLI
-
- cli* p_cli = new cli;
- p_cli->run();
+ cli* p_cli = new cli;
+ p_cli->run();
#endif
#endif
- //<<*
- // Initialize database connection queue
-#ifdef DATABASE
- wrap::DATA->initialize_connections();
-#endif
- //*>>
+ // start the socket manager. this one will listen for incoming http requests and will
+ // forward them to the specified routines which will generate a http response.
+ wrap::SOCK->start();
- // start the socket manager. this one will listen for incoming http requests and will
- // forward them to the specified routines which will generate a http response.
- wrap::SOCK->start();
+ cout << DOWNMSG << endl;
- cout << DOWNMSG << endl;
- return 0;
+ return 0;
}
diff --git a/src/maps/hmap.h b/src/maps/hmap.h
index 38ea2e4..a0824ec 100644
--- a/src/maps/hmap.h
+++ b/src/maps/hmap.h
@@ -9,6 +9,11 @@
using namespace std;
+// void add_elem( obj_type x, key_type k ) --> Insert x
+// void del_elem( key_type k ) --> Remove x
+// obj_type get_elem( key_type k ) --> Return item that matches x
+// void make_empty( ) --> Remove all items
+
template <class obj_type, class key_type>
class hmap
{
@@ -72,7 +77,6 @@ public:
virtual void make_empty( );
virtual void make_empty( void (*func)(key_type) );
virtual void del_elem ( const key_type &k );
- virtual void rename_key ( const key_type &k1, const key_type &k2 );
virtual obj_type set_elem ( const obj_type &x, const key_type &k );
virtual void run_func( void (*func)(obj_type) );
diff --git a/src/maps/hmap.tmpl b/src/maps/hmap.tmpl
index dcd0426..10facac 100644
--- a/src/maps/hmap.tmpl
+++ b/src/maps/hmap.tmpl
@@ -104,17 +104,6 @@ void hmap<obj_type, key_type>::del_elem( const key_type & k )
array[ i_current_pos ].info = DELETED;
}
-// Remove item x from the hash table.
-template <class obj_type, class key_type>
-void hmap<obj_type, key_type>::rename_key( const key_type & k1, const key_type & k2 )
-{
- int i_current_pos = find_pos( k1 );
- if( is_active( i_current_pos ) ) {
- array[ i_current_pos ].info = DELETED;
- add_elem( array[ i_current_pos ].element, k2 );
- }
-}
-
// Finds item x and resets its value.
template <class obj_type, class key_type>
obj_type hmap<obj_type, key_type>::set_elem( const obj_type & x, const key_type & k )
diff --git a/src/maps/mtools.h b/src/maps/mtools.h
index 4ee45b8..f32a49e 100644
--- a/src/maps/mtools.h
+++ b/src/maps/mtools.h
@@ -1,6 +1,7 @@
#ifndef MTOOLS_H
#define MTOOLS_H
+
template <class type_>
struct mtools
{
@@ -8,4 +9,7 @@ struct mtools
};
#include "mtools.tmpl"
-#endif
+
+#endif
+
+
diff --git a/src/maps/mtools.tmpl b/src/maps/mtools.tmpl
index 6917131..dd3f89e 100644
--- a/src/maps/mtools.tmpl
+++ b/src/maps/mtools.tmpl
@@ -3,10 +3,9 @@
template <class type_>
void
-mtools<type_>::delete_obj( type_ type_obj )
-{
+mtools<type_>::delete_obj( type_ type_obj ) {
if ( type_obj )
- delete type_obj;
+ delete type_obj;
}
#endif
diff --git a/src/maps/smap.h b/src/maps/smap.h
index 2096139..e056519 100644
--- a/src/maps/smap.h
+++ b/src/maps/smap.h
@@ -30,7 +30,6 @@ class smap : public hmap<obj_type, key_type>
void add_elem ( const obj_type &x, const key_type &k );
obj_type set_elem ( const obj_type &x, const key_type &k );
void del_elem ( const key_type &k );
- void rename_key ( const key_type &k1, const key_type &k2 );
bool is_avail ( const key_type &k );
obj_type get_elem ( const key_type &k );
obj_type pop_elem ( const key_type &k );
diff --git a/src/maps/smap.tmpl b/src/maps/smap.tmpl
index 5ec7d38..3167504 100644
--- a/src/maps/smap.tmpl
+++ b/src/maps/smap.tmpl
@@ -77,14 +77,6 @@ smap<obj_type, key_type>::del_elem( const key_type & k )
pthread_mutex_unlock( &mut_smap );
}
-template <class obj_type, class key_type> void
-smap<obj_type, key_type>::rename_key( const key_type & k1, const key_type & k2 )
-{
- pthread_mutex_lock ( &mut_smap );
- hmap<obj_type,key_type>::rename_key( k1, k2 );
- pthread_mutex_unlock( &mut_smap );
-}
-
template <class obj_type, class key_type>
obj_type smap<obj_type, key_type>::get_elem( const key_type &k )
diff --git a/src/modl.cpp b/src/modl.cpp
index 6668109..ca620ce 100755
--- a/src/modl.cpp
+++ b/src/modl.cpp
@@ -1,4 +1,5 @@
-#ifndef MODL_CPP
+#ifndef MODL_CPP
+
#define MODL_CPP
#include <limits.h>
@@ -11,152 +12,149 @@
using namespace std;
-modl::modl()
+modl::modl( ) : smap<dynmod*,string>(HMAPOCC)
{
#ifdef NCURSES
- print_cached( 0 );
+ print_cached( 0 );
#endif
+
+ if ( wrap::CONF->get_elem( "httpd.modules.preloadcommands" ).compare( "true" ) == 0 )
+ preload_modules( wrap::CONF->get_elem("httpd.modules.commandsdir") );
- if ( wrap::CONF->get_elem( "httpd.modules.preloadcommands" ).compare( "true" ) == 0 )
- preload_modules( wrap::CONF->get_elem("httpd.modules.commandsdir") );
-
- if ( wrap::CONF->get_elem( "httpd.modules.preloadhtml" ).compare( "true" ) == 0 )
- preload_modules( wrap::CONF->get_elem("httpd.modules.htmldir") );
+ if ( wrap::CONF->get_elem( "httpd.modules.preloadhtml" ).compare( "true" ) == 0 )
+ preload_modules( wrap::CONF->get_elem("httpd.modules.htmldir") );
}
modl::~modl()
{
- // dlclose all the_module's first!
- run_func( &modl::dlclose_ );
+ // dlclose all the_module's first!
+ run_func( &modl::dlclose_ );
- // then clean the hash map.
- unload_modules();
+ // then clean the hash map.
+ unload_modules();
}
void
modl::preload_modules( string s_path )
{
- dir* p_dir = new dir();
- p_dir->open_dir( s_path );
+ dir* p_dir = new dir();
+ p_dir->open_dir( s_path );
- p_dir->read_dir();
+ p_dir->read_dir();
+
+ vector<string> dir_vec = p_dir->get_dir_vec();
- vector<string> dir_vec = p_dir->get_dir_vec();
+ if ( ! dir_vec.empty() )
+ {
+ vector<string>::iterator iter = dir_vec.begin();
- if ( ! dir_vec.empty() )
+ do
{
- vector<string>::iterator iter = dir_vec.begin();
-
- do
- {
- if ( iter->length() >= 3 && iter->compare( iter->length()-3, 3, ".so" ) == 0 )
- cache_module( s_path + *iter, false );
- }
- while ( ++iter != dir_vec.end() );
+ if ( iter->length() >= 3 && iter->compare( iter->length()-3, 3, ".so" ) == 0 )
+ cache_module( s_path + *iter );
}
+ while ( ++iter != dir_vec.end() );
+ }
- dir_vec.clear();
+ dir_vec.clear();
- // This also closes the dir.
- delete p_dir;
+ // This also closes the dir.
+ delete p_dir;
}
void
modl::dlclose_( dynmod* mod )
{
- dlclose( mod->the_module );
- free ( mod );
+ dlclose( mod->the_module );
+ free ( mod );
}
dynmod*
-modl::cache_module( string s_name, bool b_print_sys_msg )
+modl::cache_module( string s_name )
{
- void *the_module = NULL;
- function *the_func = NULL;
+ void *the_module = NULL;
+ function *the_func = NULL;
- the_module = dlopen( s_name.c_str(), RTLD_LAZY );
- //the_module = dlopen( s_name.c_str(), RTLD_NOW );
+ the_module = dlopen( s_name.c_str(), RTLD_LAZY );
+ //the_module = dlopen( s_name.c_str(), RTLD_NOW );
- if ( the_module == NULL )
- {
- wrap::system_message( dlerror() );
- return NULL;
- }
+ if ( the_module == NULL )
+ {
+ wrap::system_message( dlerror() );
+ return NULL;
+ }
- the_func = (function*) dlsym( the_module, "extern_function" );
+ the_func = (function*) dlsym( the_module, "extern_function" );
- if ( the_func == NULL )
- {
- wrap::system_message( dlerror() );
- return NULL;
- }
+ if ( the_func == NULL )
+ {
+ wrap::system_message( dlerror() );
+ return NULL;
+ }
- if ( b_print_sys_msg )
- wrap::system_message( MODULEC + s_name.substr( s_name.find_last_of("/")+1 ) );
+ wrap::system_message( MODULEC + s_name.substr( s_name.find_last_of("/")+1 ) );
- dynmod *mod = new dynmod; // encapsulates the function and module handler.
- mod->the_func = the_func ; // the function to execute
- mod->the_module = the_module; // the module handler to close if function
- // is not needed anymore.
- add_elem( mod, s_name );
+ dynmod *mod = new dynmod; // encapsulates the function and module handler.
+ mod->the_func = the_func ; // the function to execute
+ mod->the_module = the_module; // the module handler to close if function
- // DO NOT CLOSE AS LONG THERE EXIST A POINTER TO THE FUNCTION
- // dlclose( module ); will be called in modl::~modl()!
+ // is not needed anymore.
+ add_elem( mod, s_name );
-#ifdef NCURSES
+ // DO NOT CLOSE AS LONG THERE EXIST A POINTER TO THE FUNCTION
+ // dlclose( module ); will be called in modl::~modl()!
- print_cached( size() );
+#ifdef NCURSES
+ print_cached( get_size() );
#endif
-
- return mod;
+
+ return mod;
}
dynmod*
modl::get_module( string s_name )
{
- wrap::system_message( MODULER + s_name.substr( s_name.find_last_of("/")+1 ) );
- dynmod* mod = get_elem( s_name );
- return ! mod ? cache_module( s_name, true ) : mod;
+ wrap::system_message( MODULER + s_name.substr( s_name.find_last_of("/")+1 ) );
+ dynmod* mod = get_elem( s_name );
+ return ! mod ? cache_module( s_name ) : mod;
}
void
modl::unload_modules()
{
- wrap::system_message( MODUNLO );
+ wrap::system_message( MODUNLO );
- // dlclose all the_module's first!
- run_func( &modl::dlclose_ );
-
- // then clean the hash map.
- shashmap<dynmod*>::clear();
+ // dlclose all the_module's first!
+ run_func( &modl::dlclose_ );
+
+ // then clean the hash map.
+ make_empty();
#ifdef NCURSES
-
- print_cached( size() );
+ print_cached( get_size() );
#endif
-
+
}
void
modl::reload_modules()
{
- unload_modules();
+ unload_modules();
- wrap::system_message( MODRELO );
- preload_modules( wrap::CONF->get_elem("httpd.modules.commandsdir") );
- preload_modules( wrap::CONF->get_elem("httpd.modules.htmldir") );
+ wrap::system_message( MODRELO );
+ preload_modules( wrap::CONF->get_elem("httpd.modules.commandsdir") );
+ preload_modules( wrap::CONF->get_elem("httpd.modules.htmldir") );
}
-
#ifdef NCURSES
void
modl::print_cached( int i_mods )
{
- if ( !wrap::NCUR->is_ready() )
- return;
+ if ( !wrap::NCUR->is_ready() )
+ return;
- mvprintw( NCUR_CACHED_MODS_X, NCUR_CACHED_MODS_Y, "Mods: %d ", i_mods);
- refresh();
+ mvprintw( NCUR_CACHED_MODS_X, NCUR_CACHED_MODS_Y, "Mods: %d ", i_mods);
+ refresh();
}
#endif
diff --git a/src/modl.h b/src/modl.h
index 983bdda..50587cd 100755
--- a/src/modl.h
+++ b/src/modl.h
@@ -3,36 +3,35 @@
#ifndef MODL_H
#define MODL_H
-#include "maps/shashmap.h"
+#include "maps/smap.h"
using namespace std;
-class modl : private shashmap<dynmod*>
+class modl : private smap<dynmod*,string>
{
private:
- static void dlclose_( dynmod* mod );
- dynmod* cache_module ( string s_name, bool b_print_sys_msg );
- void preload_modules( string s_path );
+ static void dlclose_( dynmod* mod );
+ dynmod* cache_module ( string s_name );
+ void preload_modules( string s_path );
#ifdef NCURSES
-
- void print_cached( int i_mods );
+ void print_cached( int i_mods );
#endif
public:
- modl();
- ~modl();
+ modl();
+ ~modl();
- dynmod* get_module( string s_name );
+ dynmod* get_module( string s_name );
- vector<string>* get_mod_vector()
- {
- vector<string>* p_ret = get_key_vector();
- return p_ret;
- }
+ vector<string>* get_mod_vector()
+ {
+ vector<string>* p_ret = get_key_vector();
+ return p_ret;
+ }
- void unload_modules();
- void reload_modules();
+ void unload_modules();
+ void reload_modules();
};
#endif
diff --git a/src/msgs.h b/src/msgs.h
index cedbb8b..5937e53 100755..100644
--- a/src/msgs.h
+++ b/src/msgs.h
@@ -4,12 +4,12 @@
// alphabetical ordered:
#define ACCPERR "Sock: Accept error "
#define BINDERR "Sock: Bind error "
-#define CHATREP "Chat: Using replacement strings"
-#define CHATDOP "Chat: Default operator login "
+#define HTTPDREP "Chat: Using replacement strings"
+#define HTTPDDOP "Chat: Default operator login "
#define CFILEOK "Parsing config file"
#define CFILEFA "Failed opening config file!"
-#define CONTACT "Contact: http://www.yChat.org, Mail@yChat.org, ICQ: 11655527"
-#define CLRHTML "HTML: Cleared the document cache "
+#define CONTACT "Contact: http://www.yhttpd.org, Mail@yhttpd.org, ICQ: 11655527"
+#define CLRHTML "HTML: Cleared the template cache "
#define CLIWELC "Command Line Interface (type help for a list of all commands)"
#define CLIPRMO ">> "
#define CLIPRMI "<< "
@@ -25,9 +25,9 @@
#define DATAIN1 "Data: Initializing mincon to "
#define DATAMAX "Data: Max database connections reached "
#define DATAMA0 "Data: Max database connections "
-#define DATANEW "Data: Creating new database connection "
+#define DATANEW "Data: Creating new database conbbnection "
#define DESCRIP "Copyright (C) 2003 Paul C. Buetow, Volker Richter"
-#define DESCRI2 "Copyright (C) 2004, 2005 Paul C. Buetow"
+#define DESCRI2 "Copyright (C) 2004 Paul C. Buetow"
#define DONEMSG "done"
#define DOWNMSG "Shutting down "
#define GARBAGE "Garbage: Initializing collector "
@@ -44,33 +44,23 @@
#define LOGINE1 "Chat: Login failed (alpha nick), nick: "
#define LOGINE2 "Chat: Login failed (nick length), nick: "
#define LOGINE3 "Chat: Login failed (room length), nick/room: "
-#define LOGINE4 "Chat: Login failed (guests disabled), nick: "
#define MODULEC "Modl: Caching "
#define MODULER "Modl: Requesting "
#define MODUNLO "Modl: Unloading all modules "
#define MODRELO "Modl: Reloading all modules "
-
#ifdef DATABASE
-#define MYSQLQU "MySQL: "
-#define MYSQLQ2 "MySQL: Adding query "
+#define MYSQLQU "MySQL: "
+#define MYSQLQ2 "MySQL: Adding query "
#define MYSQLE1 "MySQL: Error running mysql_init "
#endif
-
#define NCURADM "ADMINISTRATOR's MAIN MENU"
#define NCURMSG "SERVER SYSTEM MESSAGES"
-#define NCURSE0 "HTTP server: "
-#define NCURSE1 "Thread pool: "
-#define NCURSE2 "Data stats: "
-#define NCURSE3 "Chat stats: "
-#define NCURSE4 "Caching: "
#define NEWREQU "Sock: New request "
#define NEWROOM "Chat: New room "
#define NEWUSER "Chat: New user "
#define OFFFOUND "HTML: File not found "
#define PERMSTD "Reading standard command exec permissions"
#define POOLERR "Pool: Malloc error "
-#define POOLER2 "Pool: Max pool size reached ("
-#define POOLFLL "Pool: Allocating new thread ("
#define READERR "Sock: Read error "
#define REMROOM "Garbage: Removing room "
#define REMUSER "Garbage: Removing user "
@@ -92,7 +82,7 @@
#define SOCKER2 "Sock: Unknown hostname "
#define SOCKRDY "Sock: Server socket is ready "
#define SSLINIT "SSL: Initializing OpenSSL"
-#define TECACHE "HTML: Caching document "
+#define TECACHE "HTML: Caching template "
#define THRDSTR "Thread: Running"
#define TIMERAT "Timer: User autoaway timeout "
#define TIMERIN "Timer: Initializing "
@@ -103,20 +93,9 @@
#define XMLREAD "XML: Reading "
#define XMLERR "XML Error: "
#define XMLER1 "XML Error: Unable to load file "
-#define VERSION "0.7.7"
+#define VERSION "yhttpd 0.7"
#define BRANCH "RELEASE"
-#define BUILDNR 3384
-#define UNAME "FreeBSD 5.3-RELEASE-p5 i386"
-#define COMPOPT "Using built-in specs.; Configured with: FreeBSD/i386 system compiler; Thread model: posix; gcc version 3.4.2 [FreeBSD] 20040728; 3.4; g++"
-#define YCUSAGE "Usage: ./ychat {h|v}|{o confkey confvalue}\n"
-
-#define HEADER1 "HTTP/1.0 200 OK\r\n"
-#define HEADER2 "Server: yChat/" VERSION "-" BRANCH "\r\n"
-#define HEADER3 "Cache-control: no-cache\r\n"
-#define HEADER4 "Pragma: no-cache\r\n"
-#define HEADER5 "Transfer-Encoding: chunked\r\n"
-#define HEADER6 "Connection: keep-alive\r\n"
-#define HEADER7 "Content-Length: ";
-#define HEADER8 "Content-Type: ";
+#define BUILDNR 2798
+#define UNAME "FreeBSD 5.2.1-RELEASE-p10 i386"
#endif
diff --git a/src/name.cpp b/src/name.cpp
index 79167f5..646b4d9 100755
--- a/src/name.cpp
+++ b/src/name.cpp
@@ -1,3 +1,5 @@
+// class name implementation.
+
#ifndef NAME_CPP
#define NAME_CPP
@@ -8,42 +10,42 @@ using namespace std;
name::name()
{
- pthread_mutex_init( &mut_s_name, NULL);
+ pthread_mutex_init( &mut_s_name, NULL);
}
-
name::name( string s_name )
{
- pthread_mutex_init( &mut_s_name, NULL);
- set_name( s_name );
+ pthread_mutex_init( &mut_s_name, NULL);
+ set_name( s_name );
}
name::~name()
{
- pthread_mutex_destroy( &mut_s_name );
+ pthread_mutex_destroy( &mut_s_name );
}
string
-name::get_name()
+name::get_name()
{
- string s_ret;
- pthread_mutex_lock ( &mut_s_name );
- s_ret = s_name;
- pthread_mutex_unlock( &mut_s_name );
- return s_ret;
+ string s_ret;
+ pthread_mutex_lock ( &mut_s_name );
+ s_ret = s_name;
+ pthread_mutex_unlock( &mut_s_name );
+ return s_ret;
}
string
-name::get_lowercase_name()
+name::get_lowercase_name()
{
- return tool::to_lower( get_name() );
+ return tool::to_lower( get_name() );
}
void
name::set_name( string s_name )
{
- pthread_mutex_lock ( &mut_s_name );
- this->s_name = s_name;
- pthread_mutex_unlock( &mut_s_name );
+ pthread_mutex_lock ( &mut_s_name );
+ this->s_name = s_name;
+ pthread_mutex_unlock( &mut_s_name );
}
+
#endif
diff --git a/src/name.h b/src/name.h
index 0a62c1f..d5a67da 100755
--- a/src/name.h
+++ b/src/name.h
@@ -1,3 +1,4 @@
+// class name declaration.
#include "incl.h"
#ifndef NAME_H
@@ -8,17 +9,20 @@ using namespace std;
class name
{
protected:
- string s_name; // object's name.
- pthread_mutex_t mut_s_name;
+ // private members:
+ string s_name; // object's name.
+ pthread_mutex_t mut_s_name;
public:
- virtual string get_name ( );
- virtual string get_lowercase_name ( );
- virtual void set_name ( string s_name );
+ virtual string get_name ( );
+ virtual string get_lowercase_name ( );
+ virtual void set_name ( string s_name );
+
+ // public methods:
+ name( );
+ name( string s_name ); // a standard constructor.
+ ~name( );
- name();
- name( string s_name ); // a standard constructor.
- ~name();
};
#endif
diff --git a/src/ncur/menu.cpp b/src/ncur/menu.cpp
index dcacc9b..c5734a5 100755
--- a/src/ncur/menu.cpp
+++ b/src/ncur/menu.cpp
@@ -6,111 +6,112 @@
#ifndef MENU_CPP
#define MENU_CPP
-using namespace std;
-menu::menu( int i_startx, int i_starty, int i_width, int i_height, char *c_header, char **choices, int i_numchoices, const chtype ch )
+using namespace std; menu::menu( int i_startx, int i_starty, int i_width, int i_height, char *c_header, char **choices, int i_numchoices, const chtype ch )
{
- this->i_startx = i_startx;
- this->i_starty = i_starty;
- this->i_height = i_height;
- this->i_width = i_width;
- this->c_header = c_header;
- this->choices = choices;
- this->i_numchoices = i_numchoices;
-
- initialize( ch );
+ this->i_startx = i_startx;
+ this->i_starty = i_starty;
+ this->i_height = i_height;
+ this->i_width = i_width;
+ this->c_header = c_header;
+ this->choices = choices;
+ this->i_numchoices = i_numchoices;
+
+ initialize( ch );
}
menu::~menu()
{
- /*
- wborder(win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
- wrefresh(win);
- delwin(win);
- */
+ /*
+ wborder(win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
+ wrefresh(win);
+ delwin(win);
+ */
}
void
menu::initialize( const chtype ch )
{
- this->i_highlight = 1;
- this->i_choice = 0;
+ this->i_highlight = 1;
+ this->i_choice = 0;
- win = newwin( i_height, i_width, i_starty, i_startx );
- wbkgd(win, ch);
+ win = newwin( i_height, i_width, i_starty, i_startx );
+ wbkgd(win, ch);
}
void
menu::display()
{
- int x, y, i;
+ int x, y, i;
- x = 2;
- y = 2;
+ x = 2;
+ y = 2;
- box( win, 0, 0 );
- mvwprintw( win, y++, x, "%s", c_header );
+ box( win, 0, 0 );
+ mvwprintw( win, y++, x, "%s", c_header );
- for( i = 0; i < i_numchoices; i++ )
- {
- ++y;
-
- if( i_highlight == i+1 ) // Highlight the current selection.
- {
- wattron( win, A_REVERSE);
- mvwprintw( win, y, x, "%d. %s", i, choices[i]);
- wattroff( win, A_REVERSE);
- } else
+ for( i=0; i<i_numchoices; i++ )
{
- mvwprintw( win, y, x, "%d. %s", i, choices[i]);
+ y++;
+
+ if( i_highlight == i + 1 ) /* High light the present choice */
+ {
+ wattron( win, A_REVERSE);
+ mvwprintw( win, y, x, "%d. %s", i, choices[i]);
+ wattroff( win, A_REVERSE);
+ }
+ else
+ {
+ mvwprintw( win, y, x, "%d. %s", i, choices[i]);
+ }
}
- }
- wrefresh( win );
+ wrefresh( win );
}
void
menu::start( void (*swich_case_menu_action)(int) )
{
- refresh();
- bool b_flag = 1;
+ refresh();
+ bool b_flag = 1;
- while( b_flag )
- {
- keypad(win, 1);
- display();
- c = wgetch( win );
-
- switch(c)
+ while( b_flag )
{
- case KEY_UP:
- if( i_highlight == 1 )
- i_highlight = i_numchoices;
- else
- --i_highlight;
- break;
-
- case KEY_DOWN:
- if( i_highlight == i_numchoices )
- i_highlight = 1;
- else
- ++i_highlight;
- break;
-
- case 10:
- i_choice = i_highlight;
- break;
-
- default:
- mvprintw( NCUR_MENU_CHAR_X, NCUR_MENU_CHAR_Y, "%3d %c ", c, c);
- refresh();
- break;
+ keypad(win, 1);
+ display();
+ c = wgetch( win );
+
+ switch(c)
+ {
+ case KEY_UP:
+ if( i_highlight == 1 )
+ i_highlight = i_numchoices;
+ else
+ --i_highlight;
+ break;
+
+ case KEY_DOWN:
+ if( i_highlight == i_numchoices )
+ i_highlight = 1;
+ else
+ ++i_highlight;
+ break;
+
+ case 10:
+ i_choice = i_highlight;
+ break;
+
+ default:
+ mvprintw( NCUR_MENU_CHAR_X, NCUR_MENU_CHAR_Y, "%3d %c ", c, c);
+ refresh();
+ break;
+ }
+
+
+ // Menu action.
+ ( *swich_case_menu_action ) ( i_choice );
+ i_choice = 0;
}
-
- // Menu action.
- ( *swich_case_menu_action ) ( i_choice );
- i_choice = 0;
- }
}
#endif
diff --git a/src/ncur/menu.h b/src/ncur/menu.h
index af7dbe9..7e4fc5b 100755
--- a/src/ncur/menu.h
+++ b/src/ncur/menu.h
@@ -1,7 +1,6 @@
#include "../incl.h"
#ifdef NCURSES
-
#ifndef MENU_H
#define MENU_H
@@ -12,27 +11,23 @@ using namespace std;
class menu
{
private:
- char **choices;
- char *c_header;
+ char **choices;
+ char *c_header;
- int i_startx, i_starty, i_width, i_height, i_highlight, i_choice,
- i_numchoices, c;
+ int i_startx, i_starty, i_width, i_height, i_highlight, i_choice,
+ i_numchoices, c;
- WINDOW *win;
+ WINDOW *win;
- void initialize( const chtype ch );
+ void initialize( const chtype ch );
public:
- explicit menu( int i_startx, int i_starty, int i_width, int i_height, char *c_header, char **choices, int i_numchoices, const chtype ch );
- ~menu( );
-
- void display();
- void start( void (*swich_case_menu_action)(int) );
+ explicit menu( int i_startx, int i_starty, int i_width, int i_height, char *c_header, char **choices, int i_numchoices, const chtype ch );
+ ~menu( );
- void activate_menu_win()
- {
- keypad(win, 1);
- }
+ void display();
+ void start( void (*swich_case_menu_action)(int) );
+ void activate_menu_win() { keypad(win, 1); }
};
#endif
diff --git a/src/ncur/ncur.cpp b/src/ncur/ncur.cpp
index 4f63f01..e9e7753 100755
--- a/src/ncur/ncur.cpp
+++ b/src/ncur/ncur.cpp
@@ -11,282 +11,253 @@ using namespace std;
#ifdef NCURSES
-const string GMAKE_PARAMS[] =
- { "clean_base", "clean_modules", "all"
- };
+const string GMAKE_PARAMS[] = { "clean_base", "clean_modules", "all" };
const int GMAKE_ELEMENTS = 3;
ncur::ncur( )
{
- p_messagelist = new list<char*>;
- pthread_mutex_init( &mut_messages, NULL );
- pthread_mutex_init( &mut_is_ready, NULL );
- i_message_length = 45;
- b_is_ready = false;
+ p_messagelist = new list<char*>;
+ pthread_mutex_init( &mut_messages, NULL );
+ pthread_mutex_init( &mut_is_ready, NULL );
+ i_message_length = 45;
+ b_is_ready = false;
}
ncur::~ncur()
{
- pthread_mutex_destroy( &mut_messages );
- pthread_mutex_destroy( &mut_is_ready );
+ pthread_mutex_destroy( &mut_messages );
+ pthread_mutex_destroy( &mut_is_ready );
}
void
ncur::start( void *p_void )
{
- ncur::init_ncurses();
-
- char *choices[] = {
- "Unload all modules ", //<<
- "Reload all modules ", //<<
- //>>" ",
- //>>" ",
- "Clear template cache ",
- "Run garbage collector ", //<<
- //>>" ",
- "Show max res. set size ",
- "Compile changed sources ",
- "Recompile all sources ",
- "Show source stats ",
- "Command line interface ",
- //<<*
+ ncur::init_ncurses();
+
+ char *choices[] = {
+ "Unload all modules ",
+ "Reload all modules ",
+ "Clear template cache ",
+ " ",
+ "Show max res. set size ",
+ "Compile changed sources ",
+ "Recompile all sources ",
+ "Show source stats ",
+ "Command Line Interface ",
#ifdef DATABASE
- "Close DB connections ",
#else
- " ",
#endif
- //*>>
- //>>" ",
- "Shut down server"
- };
- p_serveroutput = newwin( 19, 49, 1, 31 );
- wbkgd(p_serveroutput, COLOR_PAIR(1));
+ " ",
+ "Shut down server"
+ };
- box ( p_serveroutput, 0, 0 );
- mvwprintw( p_serveroutput, 2, 2, NCURMSG );
- wrefresh ( p_serveroutput );
+ p_serveroutput = newwin( 19, 49, 1, 31 );
+ wbkgd(p_serveroutput, COLOR_PAIR(1));
- print( string("yChat ") + VERSION );
+ box ( p_serveroutput, 0, 0 );
+ mvwprintw( p_serveroutput, 2, 2, NCURMSG );
+ wrefresh ( p_serveroutput );
+ print( VERSION );
- p_menu = new menu( 1, 1, 30, 19, NCURADM, choices, 11, COLOR_PAIR(1));
- mvprintw(NCUR_SERVER_HEADER_X,NCUR_SERVER_HEADER_Y, NCURSE0);
- mvprintw(NCUR_POOL_HEADER_X,NCUR_POOL_HEADER_Y, NCURSE1);
- mvprintw(NCUR_DATA_HEADER_X,NCUR_DATA_HEADER_Y, NCURSE2); //<<
- mvprintw(NCUR_CHAT_HEADER_X,NCUR_CHAT_HEADER_Y, NCURSE3); //<<
- mvprintw(NCUR_CACHED_HEADER_X,NCUR_CACHED_HEADER_Y, NCURSE4);
+ p_menu = new menu( 1, 1, 30, 19, NCURADM, choices, 11, COLOR_PAIR(1));
- wrap::HTML->print_cached(0);
+ mvprintw( NCUR_SERVER_HEADER_X,NCUR_SERVER_HEADER_Y, "HTTP server:");
+ mvprintw( NCUR_POOL_HEADER_X,NCUR_POOL_HEADER_Y, "Thread pool:");
+#ifdef DATABASE
+#endif
+ mvprintw( NCUR_CACHED_HEADER_X,NCUR_CACHED_HEADER_Y, "Caching:");
+ wrap::HTML->print_cached(0);
- is_ready(true);
- wrap::SMAN->print_init_ncurses(); //<<
- wrap::STAT->print_num_rooms(); //<<
+ is_ready( true );
- p_menu->start( &switch_main_menu_ );
+ p_menu->start( &switch_main_menu_ );
- shutdown();
+ shutdown();
}
void
ncur::shutdown()
{
- ncur::close_ncurses();
+ ncur::close_ncurses();
}
void
ncur::print( string *p_msg )
{
- print( *p_msg );
+ print( *p_msg );
}
void
ncur::print( string s_msg )
{
- print( (char*)s_msg.c_str() );
+ print( (char*)s_msg.c_str() );
}
void
ncur::print( char* c_print )
{
- // Removing \n
- if ( strlen(c_print) > i_message_length )
- {
- string s_tmp(c_print);
- print( s_tmp.substr( 0, i_message_length ) );
- print( s_tmp.substr( i_message_length, s_tmp.length()-i_message_length ) );
- return;
- }
-
- int i;
- char* c_temp = new char[i_message_length];
- memcpy( c_temp, c_print, strlen(c_print) );
-
- for ( i = strlen(c_print); i < i_message_length; ++i )
- c_temp[i] = ' ';
-
- c_temp[i] = '\0';
-
- pthread_mutex_lock( &mut_messages );
-
- if ( p_messagelist->size() > 12 )
- {
- char* c_front = p_messagelist->front();
- p_messagelist->pop_front();
- free(c_front);
- }
-
- p_messagelist->push_back( c_temp );
+ // Removing \n
+ if ( strlen(c_print) > i_message_length )
+ {
+ string s_tmp(c_print);
+ print( s_tmp.substr( 0, i_message_length ) );
+ print( s_tmp.substr( i_message_length, s_tmp.length()-i_message_length ) );
+ return;
+ }
+
+ int i;
+ char* c_temp = new char[i_message_length];
+ memcpy( c_temp, c_print, strlen(c_print) );
+ for ( i = strlen(c_print); i < i_message_length; i++ )
+ c_temp[i] = ' ';
+ c_temp[i] = '\0';
+
+ pthread_mutex_lock( &mut_messages );
+
+ if ( p_messagelist->size() > 12 )
+ {
+ char* c_front = p_messagelist->front();
+ p_messagelist->pop_front();
+ free( c_front );
+ }
+ p_messagelist->push_back( c_temp );
- if ( is_ready() )
- {
- list<char*>::iterator iter;
- iter = p_messagelist->begin();
- for ( i = 4; i < 18 && iter != p_messagelist->end(); ++i, ++iter )
+ if ( is_ready() )
+ {
+ list<char*>::iterator iter;
+ iter = p_messagelist->begin();
+
+ for ( i=4; i<18 && iter != p_messagelist->end(); i++, iter++ )
mvwprintw( p_serveroutput, i, 2, *iter );
- wrefresh ( p_serveroutput );
- }
+ wrefresh ( p_serveroutput );
+ }
- pthread_mutex_unlock( &mut_messages );
+ pthread_mutex_unlock( &mut_messages );
}
void
ncur::switch_main_menu_( int i_choice )
{
- int i;
-
- if( i_choice != 0 )
- switch ( i_choice )
- {
- //<<*
- case 1:
- wrap::MODL->unload_modules();
- mvprintw( 20,2, "Unloaded all modules ");
- refresh();
- break;
- case 2:
- wrap::MODL->reload_modules();
- mvprintw( 20,2, "Reloaded all modules ");
- refresh();
- break;
- //*>>
- case 3:
- wrap::HTML->clear_cache();
- mvprintw( 20,2, "Cleared the template cache ");
- refresh();
- break;
- case 4:
- //<<*
- if ( ! wrap::GCOL->remove_garbage() )
- wrap::NCUR->print( GAROFFNE );
- mvprintw( 20,2, "Garbage collector activated ");
- //*>>
- refresh();
- break;
- case 5:
- mvprintw( 20,2, "Showing max resident set size in memory ");
- wrap::NCUR->print( STATRSS + string("(") + tool::int2string(
- wrap::STAT->get_ru_maxrss()) + string(")"));
- break;
- case 6:
- tool::shell_command( string(GMAKE), METH_NCURSES);
- break;
- case 7:
- for ( i = 0; i < GMAKE_ELEMENTS; i++ )
- tool::shell_command( GMAKE + GMAKE_PARAMS[i], METH_NCURSES);
- break;
- case 8:
- tool::shell_command( string(GMAKE) + " stats", METH_NCURSES);
- break;
- case 9:
-#ifdef CLI
-
- wrap::NCUR->is_ready(false);
- refresh(); /* Print it on to the real screen */
-
- def_prog_mode(); /* Save the tty modes */
- endwin(); /* End curses mode temporarily */
- new cli(); /* Start CLI mode */
- reset_prog_mode(); /* Return to the previous tty mode*/
- /* stored by def_prog_mode() */
- refresh(); /* Do refresh() to restore the */
- /* Screen contents */
- wrap::NCUR->is_ready(true);
- wrap::NCUR->activate_menu_win();
+ int i;
+
+ if( i_choice != 0 )
+ switch ( i_choice )
+ {
+ case 1:
+ wrap::MODL->unload_modules();
+ mvprintw( 20,2, "Unloaded all modules ");
+ refresh();
+ break;
+ case 2:
+ wrap::MODL->reload_modules();
+ mvprintw( 20,2, "Reloaded all modules ");
+ refresh();
+ break;
+ case 3:
+ wrap::HTML->clear_cache();
+ mvprintw( 20,2, "Cleared the template cache ");
+ refresh();
+ break;
+ case 4:
+ refresh();
+ break;
+ case 5:
+ mvprintw( 20,2, "Showing max resident set size in memory ");
+ wrap::NCUR->print( STATRSS + string("(") + tool::int2string(
+ wrap::STAT->get_ru_maxrss()) + string(")"));
+ break;
+ case 6:
+ tool::shell_command( string(GMAKE), METH_NCURSES);
+ break;
+ case 7:
+ for ( i = 0; i < GMAKE_ELEMENTS; i++ )
+ tool::shell_command( GMAKE + GMAKE_PARAMS[i], METH_NCURSES);
+ break;
+ case 8:
+ tool::shell_command( string(GMAKE) + " stats", METH_NCURSES);
+ break;
+ case 9:
+#ifdef CLI
+ wrap::NCUR->is_ready(false);
+ refresh(); /* Print it on to the real screen */
+
+ def_prog_mode(); /* Save the tty modes */
+ endwin(); /* End curses mode temporarily */
+ new cli(); /* Start CLI mode */
+ reset_prog_mode(); /* Return to the previous tty mode*/
+ /* stored by def_prog_mode() */
+ refresh(); /* Do refresh() to restore the */
+ /* Screen contents */
+ wrap::NCUR->is_ready(true);
+ wrap::NCUR->activate_menu_win();
#else
-
- mvprintw( 20,2, "CLI mode has not been compiled in! ");
+ mvprintw( 20,2, "CLI mode has not been compiled in! ");
#endif
-
- break;
- case 10:
+ break;
+ case 10:
#ifdef DATABASE
-
- wrap::DATA->disconnect_all_connections(); //<<
#endif
-
- break;
-
- case 11: // Shut down server
- if ( ! wrap::GCOL->remove_garbage() ) //<<
- wrap::NCUR->print( GAROFFNE ); //<<
- mvprintw( 21,2, "Good bye !");
- close_ncurses();
- exit(0);
- break;
-
- default:
- mvprintw( 20,2, "Selection # %d not yet implemented!", i_choice-1);
- wrap::NCUR->print( "Selection not yet implemented!" );
- refresh();
- break;
- }
+ break;
+
+ case 11: // Shut down server
+ mvprintw( 21,2, "Good bye !");
+ close_ncurses();
+ exit(0);
+ break;
+
+ default:
+ mvprintw( 20,2, "Selection # %d not yet implemented!", i_choice-1);
+ wrap::NCUR->print( "Selection not yet implemented!" );
+ refresh();
+ break;
+ }
}
void
ncur::init_ncurses()
{
- initscr();
- start_color();
- clear();
- noecho();
- cbreak(); // Line buffering disabled. pass on everything
- init_pair(1, COLOR_WHITE, COLOR_BLUE);
- mvprintw( 0,2, (char*)(tool::ychat_version()).c_str());
- refresh();
+ initscr();
+ start_color();
+ clear();
+ noecho();
+ cbreak(); // Line buffering disabled. pass on everything
+ init_pair(1, COLOR_WHITE, COLOR_BLUE);
+ mvprintw( 0,2, (char*)(tool::yhttpd_version()).c_str());
+ refresh();
}
void
ncur::close_ncurses()
{
- refresh();
- clrtoeol();
- refresh();
- endwin();
+ refresh();
+ clrtoeol();
+ refresh();
+ endwin();
}
void
ncur::is_ready( bool b_is_ready )
{
- pthread_mutex_lock( &mut_is_ready );
- this->b_is_ready = b_is_ready;
- pthread_mutex_unlock( &mut_is_ready );
+ pthread_mutex_lock( &mut_is_ready );
+ this->b_is_ready = b_is_ready;
+ pthread_mutex_unlock( &mut_is_ready );
}
bool
ncur::is_ready()
{
- bool b_ret;
- pthread_mutex_lock( &mut_is_ready );
- b_ret = b_is_ready;
- pthread_mutex_unlock( &mut_is_ready );
- return b_ret;
+ bool b_ret;
+ pthread_mutex_lock( &mut_is_ready );
+ b_ret = b_is_ready;
+ pthread_mutex_unlock( &mut_is_ready );
+ return b_ret;
}
-
#endif
#endif
diff --git a/src/ncur/ncur.h b/src/ncur/ncur.h
index 74ed60e..692a48a 100755
--- a/src/ncur/ncur.h
+++ b/src/ncur/ncur.h
@@ -1,10 +1,8 @@
#include "../incl.h"
#ifdef NCURSES
-
#ifndef NCUR_H
#define NCUR_H
-
#include <ncurses.h>
#include <list>
@@ -16,34 +14,30 @@ using namespace std;
class ncur : public thro
{
private:
- menu* p_menu;
- WINDOW* p_serveroutput;
- list<char*>* p_messagelist; // contains the messages for p_serveroutput!
- int i_message_length; // the maximum length of a system message!
- bool b_is_ready; // is set to TRUE if the admin interface is initialized.
- static void init_ncurses();
- static void close_ncurses();
-
- pthread_mutex_t mut_messages;
- pthread_mutex_t mut_is_ready;
+ menu* p_menu;
+ WINDOW* p_serveroutput;
+ list<char*>* p_messagelist; // contains the messages for p_serveroutput!
+ pthread_mutex_t mut_messages; // for syncronization of p_serveroutput!
+ int i_message_length; // the maximum length of a system message!
+ bool b_is_ready; // is set to TRUE if the admin interface is initialized.
+ static void init_ncurses();
+ static void close_ncurses();
+ pthread_mutex_t mut_is_ready;
public:
- ncur( ); // a standard constructor.
- ~ncur( );
-
- void start( void *p_void );
- void print( char* c_print );
- void print( string s_msg );
- void print( string* p_msg );
- void is_ready( bool b_is_ready );
- bool is_ready();
- static void switch_main_menu_( int i_choice );
- void shutdown();
-
- void activate_menu_win()
- {
- p_menu->activate_menu_win();
- }
+ ncur( ); // a standard constructor.
+ ~ncur( );
+
+ void start( void *p_void );
+ virtual void print( char* c_print );
+ virtual void print( string s_msg );
+ virtual void print( string* p_msg );
+ void is_ready( bool b_is_ready );
+ bool is_ready();
+ static void switch_main_menu_( int i_choice );
+ void shutdown();
+ void activate_menu_win()
+ { p_menu->activate_menu_win(); }
};
#endif
diff --git a/src/reqp.cpp b/src/reqp.cpp
index ce75a12..630e34c 100755
--- a/src/reqp.cpp
+++ b/src/reqp.cpp
@@ -6,378 +6,292 @@
using namespace std;
-#define HEADER HEADER1 HEADER2 HEADER3 HEADER4
-#define STREAM HEADER5 HEADER6
-
-const string reqp::s_http = HEADER;
-const string reqp::s_http_stream = STREAM;
-const string reqp::s_http_colength = HEADER7;
-const string reqp::s_http_cotype = HEADER8;
+string reqp::HTTP_CODEOK = "HTTP/1.1 200 OK\r\n";
+string reqp::HTTP_SERVER = "Server: yhttpd (Unix)\r\n";
+string reqp::HTTP_CONTAC = "Contact: www.yhttpd.org\r\n";
+string reqp::HTTP_EXPIRE = "Expires: 0\r\n";
+string reqp::HTTP_CACHEC = "Cache-control: no-cache\r\nPragma: no-cache\r\n";
+string reqp::HTTP_CONNEC = "Connection: keep-alive\r\n";
+string reqp::HTTP_CHUNKE = "Transfer-Encoding: chunked\r\n";
+string reqp::HTTP_COTYPE = "Content-Type: ";
reqp::reqp( )
{}
void
-reqp::get_request_parameters( string s_parameters, hashmap<string>& map_params )
+reqp::get_request_parameters( string s_parameters, map_string& map_params )
{
- string s_tmp;
- unsigned i_pos, i_pos2;
-
- while( (i_pos = s_parameters.find("&")) != string::npos )
- {
- s_tmp = s_parameters.substr(0, i_pos );
-
- if ( (i_pos2 = s_tmp.find("=")) != string::npos )
- map_params[ s_tmp.substr(0, i_pos2) ] = tool::replace( s_tmp.substr( i_pos2+1 ), "\\AND", "&");
-
- s_parameters = s_parameters.substr( i_pos + 1 );
- }
-
- // Get the last request parameter, which does not have a "&" on the end!
- if( (i_pos = s_parameters.find("=")) != string::npos )
- map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr( i_pos+1 );
-
- //map<string,string>::iterator iter;
- //for ( iter = map_params.begin(); iter != map_params.end(); ++iter )
- //cout << ">>>" << iter->first << "=" << iter->second << endl;
+ string s_tmp;
+ unsigned i_pos, i_pos2;
+
+ while( (i_pos = s_parameters.find("&")) != string::npos )
+ {
+ s_tmp = s_parameters.substr(0, i_pos );
+
+ if ( (i_pos2 = s_tmp.find("=")) != string::npos )
+ map_params[ s_tmp.substr(0, i_pos2) ] = s_tmp.substr( i_pos2+1 );
+
+ s_parameters = s_parameters.substr( i_pos + 1 );
+ }
+
+ // Get the last request parameter, which does not have a "&" on the end!
+ if( (i_pos = s_parameters.find("=")) != string::npos )
+ map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr( i_pos+1 );
+
+ // map_string::iterator iter;
+ // for ( iter = map_params.begin(); iter != map_params.end(); ++iter )
+ // cout << ">>>" << iter->first << "=" << iter->second << endl;
}
string
-reqp::get_url( int &i_sock, string s_req, hashmap<string> &map_params )
+reqp::get_url( thrd* p_thrd, string s_req, map_string &map_params )
{
- unsigned i_pos, i_pos2;
- string s_vars( "" );
- string s_ret;
- int i_req;
-
- // GET request
- if ( s_req.find("GET") != string::npos)
- {
- // Be sure that the GET request has minimum length
- if ( s_req.length() > 5 )
+ unsigned i_pos, i_pos2;
+ string s_vars( "" );
+ string s_ret;
+ int i_req;
+
+ // GET request
+ if ( s_req.find("GET") != string::npos)
{
+ // Be sure that the GET request has minimum length
+ if ( s_req.length() > 5 )
+ {
// Get rid of "GET /"
if ( (i_pos = s_req.find("\n")) == string::npos )
- i_pos = s_req.length() - 1;
+ i_pos = s_req.length() - 1;
- s_req = s_req.substr(5, i_pos - 5);
+ s_req = s_req.substr(5, i_pos - 5);
- // Get HTML site to be displayed
+ // Get HTML site to be displayed
if ( (i_pos = s_req.find("?")) == string::npos )
{
- if ( (i_pos2 = s_req.find(" HTTP")) != string::npos )
- s_ret = url_decode( s_req.substr(0, i_pos2));
+ if ( (i_pos2 = s_req.find(" HTTP")) != string::npos )
+ s_ret = url_decode( s_req.substr(0, i_pos2));
}
+
else
{
- s_ret = url_decode( s_req.substr(0, i_pos) );
-
- // Get request parameters:
- if ( (i_pos2 = s_req.find(" HTTP")) != string::npos )
- {
- s_req = url_decode( s_req.substr(i_pos + 1, i_pos2 - i_pos - 1) );
- get_request_parameters( s_req, map_params );
- }
+ s_ret = url_decode( s_req.substr(0, i_pos) );
+
+ // Get request parameters:
+ if ( (i_pos2 = s_req.find(" HTTP")) != string::npos )
+ {
+ s_req = url_decode( s_req.substr(i_pos + 1, i_pos2 - i_pos - 1) );
+ get_request_parameters( s_req, map_params );
+ }
}
+ }
}
- }
- // POST request
- else
- {
- if ( (i_pos2 = s_req.find("HTTP")) != string::npos )
+ // POST request
+ else
{
+ if ( (i_pos2 = s_req.find("HTTP")) != string::npos )
+ {
if ( 13 < i_pos2 )
- {
- s_ret = url_decode( s_req.substr(6,i_pos2-7) );
-
- int i_len = s_ret.length();
- int i_len2 = s_req.length()-1;
-
- s_req = s_req.substr( i_len < i_len2 ? i_len : i_len2 );
-
- if ( (i_pos = s_req.find("event=")) == string::npos)
- {
- char c_req[POSTBUF];
- i_len = read(i_sock, c_req, POSTBUF);
- s_req = c_req;
- s_req = s_req.substr(0, i_len);
-
- if ( (i_pos = s_req.find("event=")) != string::npos )
- get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params );
- }
- else
- {
- get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params );
- }
+ {
+ s_ret = url_decode( s_req.substr(6,i_pos2-7) );
+
+ int i_len = s_ret.length();
+ int i_len2 = s_req.length()-1;
+
+ s_req = s_req.substr( i_len < i_len2 ? i_len : i_len2 );
+
+ if ( (i_pos = s_req.find("event=")) == string::npos)
+ {
+ char c_req[POSTBUF];
+ i_len = read(p_thrd->get_sock(), c_req, POSTBUF);
+ s_req = c_req;
+ s_req = s_req.substr(0, i_len);
+
+ if ( (i_pos = s_req.find("event=")) != string::npos )
+ get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params );
+ }
+ else
+ {
+ get_request_parameters( url_decode( s_req.substr(i_pos) ), map_params );
+ }
}
+ }
}
- }
#ifdef VERBOSE
- wrap::system_message( REQUEST + s_ret );
+ wrap::system_message( REQUEST + s_ret );
#endif
- if ( s_ret.empty() )
- s_ret = wrap::CONF->get_elem( "httpd.startsite" );
-
- else
- s_ret = remove_dots(s_ret);
+ if ( s_ret.empty() )
+ s_ret = wrap::CONF->get_elem( "httpd.startsite" );
- map_params["request"] = s_ret;
+ else
+ s_ret = remove_dots(s_ret);
+
+ map_params["request"] = s_ret;
- return s_ret;
+ return s_ret;
}
string
reqp::get_content_type( string s_file )
{
- string s_ext(tool::get_extension( s_file ));
+ string s_ext(tool::get_extension( s_file ));
- if( s_ext == "" )
- s_ext = "default";
+ if( s_ext == "" )
+ s_ext = "default";
- return wrap::CONF->get_elem( "httpd.contenttypes." + s_ext );
+ return wrap::CONF->get_elem( "httpd.contenttypes." + s_ext );
}
void
-reqp::parse_headers( string s_req, hashmap<string> &map_params )
+reqp::parse_headers( string s_req, map_string &map_params )
{
- int pos = s_req.find("\n");
-
- if (pos != string::npos)
- {
- map_params["QUERY_STRING"] = tool::trim(s_req.substr(0,pos-1));
+ int pos = s_req.find("\n");
- int pos2;
- do
+ if (pos != string::npos)
{
- string s_line( s_req.substr(0, pos) );
- pos2 = s_line.find(":");
+ map_params["QUERY_STRING"] = tool::trim(s_req.substr(0,pos-1));
+
+ do
+ {
+ string s_line( s_req.substr(0, pos) );
+ int pos2 = s_line.find(":");
- if (pos2 != string::npos && s_line.length() > pos2+1)
+ if (pos2 != string::npos && s_line.length() > pos2+1)
map_params[ tool::trim(s_line.substr(0, pos2)) ] = tool::trim(s_line.substr(pos2+1));
- s_req = s_req.substr( s_line.size() + 1 );
- pos = s_req.find("\n");
- }
- while( pos != string::npos);
- } // if
+ s_req = s_req.substr( s_line.size() + 1 );
+ pos = s_req.find("\n");
+ }
+ while( pos != string::npos);
+ } // if
}
int
-reqp::htoi(string *p_str)
+reqp::htoi(string *s)
{
- int value, c;
- c = p_str->at(0);
+ int value;
+ int c;
+
+ c = s->at(0);
- if( isupper(c) )
- c = tolower(c);
+ if( isupper(c) )
+ c = tolower(c);
- value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
+ value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
- c = p_str->at(1);
+ c = s->at(1);
- if( isupper(c) )
- c = tolower(c);
+ if( isupper(c) )
+ c = tolower(c);
- value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
+ value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
- return value;
+ return value;
}
string
-reqp::url_decode( string s_url )
+reqp::url_decode( string s_str )
{
- string s_dest = "";
- int i_len = s_url.size();
- int i_prv = i_len - 2;
-
- char c;
- for( int i = 0; i < i_len; ++i)
- {
- c = s_url.at(i);
- if( c == '+' )
- {
- s_dest += " ";
- }
- else if (c == '%' && i < i_prv)
- {
- string s_tmp = s_url.substr(i+1, 2);
- c = (char) htoi(&s_tmp);
- s_dest += c;
- i += 2;
- }
- else
+ string s_dest = "";
+ int i_len = s_str.size();
+ int i_prv = i_len - 2;
+
+ for( int i = 0; i < i_len; ++i)
{
- s_dest += c;
+ char ch = s_str.at(i);
+ if( ch == '+' )
+ {
+ s_dest += " ";
+ }
+
+ else if (ch == '%' && i < i_prv)
+ {
+ string s_tmp = s_str.substr(i+1, 2);
+ ch = (char) htoi(&s_tmp);
+ s_dest += ch;
+ i += 2;
+ }
+
+ else
+ {
+ s_dest += ch;
+ }
}
- }
- return s_dest;
+ return s_dest;
}
string
reqp::get_from_header( string s_req, string s_hdr )
{
- unsigned i_pos[2];
- if ( (i_pos[0] = s_req.find( s_hdr, 0 )) == string::npos )
- return "";
+ unsigned i_pos[2];
+ if ( (i_pos[0] = s_req.find( s_hdr, 0 )) == string::npos )
+ return "";
- if ( (i_pos[1] = s_req.find( "\n", i_pos[0]) ) == string::npos )
- return "";
+ if ( (i_pos[1] = s_req.find( "\n", i_pos[0]) ) == string::npos )
+ return "";
- unsigned i_len = s_hdr.length();
- return s_req.substr( i_pos[0] + i_len, i_pos[1] - i_pos[0] - i_len - 1 );
+ int i_len = s_hdr.length();
+ return s_req.substr( i_pos[0] + i_len, i_pos[1] - i_pos[0] - i_len - 1 );
}
string
-reqp::parse( int &i_sock, string s_req, hashmap<string> &map_params )
+reqp::parse( thrd* p_thrd, string s_req, map_string &map_params )
{
- // store all request informations in map_params. store the url in
- // map_params["request"].
- get_url( i_sock, s_req, map_params );
-
- parse_headers( s_req, map_params );
- string s_event( map_params["event"] );
-
- map_params["content-type"] = get_content_type( map_params["request"] );
-
- string s_rep( "" );
-
- //<<*
- // check the event variable.
- if ( ! s_event.empty() )
- {
- // login procedure.
- if ( s_event == "login" )
- {
- wrap::CHAT->login( map_params );
- }
- else if ( s_event == "register" )
- {
- user* p_user = new user;
- map_params["INFO"] = "";
- run_html_mod( s_event, map_params, p_user );
- wrap::GCOL->add_user_to_garbage( p_user );
+ // store all request informations in map_params. store the url in
+ // map_params["request"].
+ get_url( p_thrd, s_req, map_params );
+
+ parse_headers( s_req, map_params );
+ string s_event( map_params["event"] );
+
+ // create the http header.
+ string s_rep( HTTP_CODEOK );
+ s_rep.append( HTTP_SERVER );
+ s_rep.append( HTTP_CONTAC );
+ s_rep.append( HTTP_EXPIRE );
+ s_rep.append( HTTP_CACHEC );
+ s_rep.append( HTTP_CONNEC );
+
+ if ( s_event.compare("stream") == 0 )
+ s_rep.append( HTTP_CHUNKE );
+
+ s_rep.append( HTTP_COTYPE );
+ s_rep.append( get_content_type( map_params["request"] ) );
+ s_rep.append("\r\n\r\n");
+
+
+ if ( wrap::CONF->get_elem("httpd.enablecgi").compare("true") == 0 &&
+ string::npos != map_params["request"].find(".cgi") )
+ {
+ s_rep.append( tool::shell_command(
+ wrap::CONF->get_elem("httpd.templatedir") + map_params["request"],
+ METH_RETSTRING ) );
}
+
else
{
- sess *p_sess = wrap::SMAN->get_session( map_params["tmpid"] );
- user *p_user = NULL;
-
- if( p_sess != NULL )
- {
- p_user = p_sess->get_user();
- }
- else
- {
- return s_rep;
- }
-
- if ( ! p_user )
- {
- map_params["INFO"] = wrap::CONF->get_elem( "chat.msgs.err.notonline" );
- map_params["request"] = wrap::CONF->get_elem( "httpd.startsite" ); // redirect to the startpage.
- }
- else
- {
- map_params["nick"] = p_user->get_name().c_str();
-
- // if a message input.
- if ( s_event == "input" )
- {
- if ( p_user )
- {
- p_user->check_restore_away();
- wrap::CHAT->post( p_user, map_params );
- }
- }
-
- // if a chat stream
- else if ( s_event == "stream" )
- {
- string s_msg ( wrap::HTML->parse( map_params ) );
- p_user->msg_post( &s_msg);
- wrap::SOCK->chat_stream( i_sock, p_user, map_params );
- }
-
- // if a request for the online list of the active room.
- else if ( s_event == "online" )
- {
- wrap::HTML->online_list( p_user, map_params );
- }
- else if ( s_event != "input" )
- {
- run_html_mod( s_event, map_params, p_user );
- }
- }
+ // parse and get the requested html-template and also use
+ // the values stored in map_params for %%KEY%% substituations.
+ s_rep.append( wrap::HTML->parse( map_params ) );
}
- }
- //*>>
-
- if ( wrap::CONF->get_elem("httpd.enablecgi").compare("true") == 0 &&
- string::npos != map_params["request"].find(".cgi") )
- {
- s_rep.append( tool::shell_command(
- wrap::CONF->get_elem("httpd.templatedir") + map_params["request"],
- METH_RETSTRING ) );
- }
- else
- {
- // parse and get the requested html-template and also use
- // the values stored in map_params for %%KEY%% substituations.
- s_rep.append( wrap::HTML->parse( map_params ) );
- }
-
- // create the http header.
-
- string s_resp(s_http);
- if ( s_event.compare("stream") == 0 )
- s_resp.append( s_http_stream );
-
- s_resp.append( s_http_colength + tool::int2string(s_rep.size()) + "\n"
- + map_params["content-type"] + "\r\n\r\n" );
- s_resp.append(s_rep);
-
-
- // return the parsed html-template.
- return s_resp;
+ // return the parsed html-template.
+ return s_rep;
}
-//<<*
-void
-reqp::run_html_mod( string s_event, hashmap<string> &map_params, user* p_user )
-{
- container *c = new container;
-
- c->elem[0] = (void*) wrap::WRAP;
- c->elem[1] = (void*) &map_params;
- c->elem[2] = (void*) p_user;
-
- string s_mod = wrap::CONF->get_elem("httpd.modules.htmldir") + "yc_" + s_event + ".so";
-
- dynmod* p_module = wrap::MODL->get_module( s_mod );
-
- if ( p_module != NULL )
- ( *( p_module->the_func ) ) ( (void*) c );
-
- delete c;
-}
-//*>>
string
reqp::remove_dots( string s_ret )
{
- // remove ".." from the request.
- unsigned pos;
+ // remove ".." from the request.
+ unsigned pos;
- if( (pos = s_ret.find( ".." )) != string::npos)
- return s_ret.substr(0, pos);
+ if( (pos = s_ret.find( ".." )) != string::npos)
+ return s_ret.substr(0, pos);
- return s_ret;
+ return s_ret;
}
#endif
diff --git a/src/reqp.h b/src/reqp.h
index 6dc8c2d..3a998b9 100755
--- a/src/reqp.h
+++ b/src/reqp.h
@@ -1,41 +1,49 @@
#include "incl.h"
+
#ifndef REQP_H
#define REQP_H
-#include "maps/hashmap.h"
+#include <map>
+#include "thrd/thrd.h"
using namespace std;
+typedef map<string, string, less<string> > map_string;
+
class reqp
{
private:
- static const string s_http;
- static const string s_http_stream;
- static const string s_http_colength;
- static const string s_http_cotype;
-
- // returns the request url from thr client's http request header
- // until the first "?" and stores all request parameter values
- // ( behind "?" ) into map_params.
- string get_url( int &i_sock, string s_req, hashmap<string> &map_params );
- // returns a specific value of the client's http request header.
- // ( s.t. like the User-Agent, Referer etc... ).
- string get_from_header( string s_req, string s_hdr );
-
- int htoi( string *p_str );
- void run_html_mod( string s_event, hashmap<string> &map_params, user* p_user ); //<<
- // Removes double dots ".."
- string remove_dots( string s_req );
-
- // Parses "event=bla?blu=bli&sadasda=asddds ..." string and stores them in the map
- void get_request_parameters( string s_parameters, hashmap<string>& map_params );
+ static string HTTP_CODEOK,
+ HTTP_CODENF,
+ HTTP_EXPIRE,
+ HTTP_SERVER,
+ HTTP_CONTAC,
+ HTTP_CACHEC,
+ HTTP_CONNEC,
+ HTTP_CHUNKE,
+ HTTP_COTYPE;
+
+ // returns the request url from thr client's http request header
+ // until the first "?" and stores all request parameter values
+ // ( behind "?" ) into map_params.
+ virtual string get_url( thrd* p_thrd, string s_req, map_string &map_params );
+ // returns a specific value of the client's http request header.
+ // ( s.t. like the User-Agent, Referer etc... ).
+ virtual string get_from_header( string s_req, string s_hdr );
+
+ virtual int htoi( string *s );
+ // Removes double dots ".."
+ string remove_dots( string s_req );
+
+ // Parses "event=bla?blu=bli&sadasda=asddds ..." string and stores them in the map
+ void get_request_parameters( string s_parameters, map_string& map_params );
public:
- reqp( );
- string parse( int &i_sock, string s_req, hashmap<string> &map_params );
- string url_decode ( string s_url );
- string get_content_type( string s_file );
- void parse_headers( string s_req, hashmap<string> &map_params );
+ reqp( );
+ virtual string parse( thrd* p_thrd, string s_req, map_string &map_params );
+ virtual string url_decode ( string );
+ virtual string get_content_type( string );
+ virtual void parse_headers( string s_req, map_string &map_params );
};
#endif
diff --git a/src/sock/sock.cpp b/src/sock/sock.cpp
index 802a980..7dba4b7 100755
--- a/src/sock/sock.cpp
+++ b/src/sock/sock.cpp
@@ -6,303 +6,251 @@
#include <sys/types.h>
#include <unistd.h>
#include "sock.h"
-#include "../chat/chat.h"
-#include "../chat/user.h"
using namespace std;
sock::sock()
{
- this->b_run = true;
- this->i_req = 0;
- this->i_threads = 0;
- this->req_parser = new reqp();
- this->thrd_pool = new pool();
-#ifdef LOGGING
-
- this->log_daemon = new logd( wrap::CONF->get_elem( "httpd.logging.accessfile" ),
-
- wrap::CONF->get_elem( "httpd.logging.accesslines" ) );
-#endif
+ this->b_run = true;
+ this->i_req = 0;
+ this->i_threads = 0;
+ this->req_parser = new reqp();
+ this->thrd_pool = new pool();
+ this->log_daemon = new logd( wrap::CONF->get_elem( "httpd.logging.accessfile" ),
+ wrap::CONF->get_elem( "httpd.logging.accesslines" ) );
+
+ pthread_mutex_init( &mut_threads, NULL );
}
sock::~sock()
-{}
-
-//<<*
-void
-sock::chat_stream( int i_sock, user *p_user, hashmap<string> &map_params )
{
- string s_msg( "\n" );
-
- for ( int i = 0; i < PUSHSTR; i++ )
- send( i_sock, s_msg.c_str(), s_msg.size(), 0 );
-
- pthread_mutex_t mutex;
- pthread_mutex_init( &mutex, NULL );
- pthread_mutex_lock( &mutex );
-
- do
- {
- s_msg = p_user->get_mess( );
-
- if ( 0 > send( i_sock, s_msg.c_str(), s_msg.size(), 0 ) )
- {
- p_user->set_online( false );
- break;
- }
-
- pthread_cond_wait( &(p_user->cond_message), &mutex );
- }
- while( p_user->get_online() );
-
- pthread_mutex_destroy( &mutex );
-
- // if there is still a message to send:
- s_msg = p_user->get_mess( );
-
- if ( ! s_msg.empty() )
- send( i_sock, s_msg.c_str(), s_msg.size(), 0 );
-
- // remove the user from its room.
- string s_user( p_user->get_name() );
- string s_user_lowercase( p_user->get_lowercase_name() );
-
- p_user->get_room()->del_elem( s_user_lowercase );
-
- // post the room that the user has left the chat.
- s_msg = wrap::TIMR->get_time() + " "
- + p_user->get_colored_bold_name()
- + wrap::CONF->get_elem( "chat.msgs.userleaveschat" )
- + "<br>\n";
-
- p_user->get_room()->msg_post( &s_msg );
- p_user->get_room()->reload_onlineframe();
-
-#ifdef VERBOSE
-
- cout << REMUSER << s_user << endl;
-#endif
-
- wrap::GCOL->add_user_to_garbage( p_user );
+ pthread_mutex_destroy( &mut_threads );
}
-//*>>
+
int
sock::make_server_socket( int i_port )
{
- size_t i_sock;
- struct sockaddr_in name;
+ size_t sock;
+ struct sockaddr_in name;
- // create the server socket.
- i_sock = socket (PF_INET, SOCK_STREAM, 0);
- if (i_sock < 0)
- {
- wrap::system_message( SOCKERR );
+ // create the server socket.
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ wrap::system_message( SOCKERR );
- if ( ++i_port > MAXPORT )
- exit(1);
+ if ( ++i_port > MAXPORT )
+ exit(-1);
- wrap::system_message( SOCKERR );
+ wrap::system_message( SOCKERR );
- return make_server_socket( i_port );
- }
+ return make_server_socket( i_port );
+ }
- // give the server socket a name.
- name.sin_family = AF_INET;
- name.sin_port = htons(i_port);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
- int i_optval = 1;
+ // give the server socket a name.
+ name.sin_family = AF_INET;
+ name.sin_port = htons (i_port);
+ name.sin_addr.s_addr = htonl (INADDR_ANY);
+ int optval=1;
- setsockopt( i_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i_optval, sizeof(int) );
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));
- if ( bind(i_sock, (struct sockaddr *) &name, sizeof (name)) < 0 )
- {
+ if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
+ {
- wrap::system_message( BINDERR );
+ wrap::system_message( BINDERR );
- if ( ++i_port > MAXPORT )
- exit(1);
+ if ( ++i_port > MAXPORT )
+ exit(-1);
- wrap::system_message( string(SOCKERR) + tool::int2string(i_port) );
+ wrap::system_message( string(SOCKERR) + tool::int2string(i_port) );
- // Rerun recursive.
- return make_server_socket( i_port );
- }
+ return make_server_socket( i_port );
+ }
- wrap::system_message( SOCKCRT + string("localhost:") + tool::int2string(i_port) );
+ wrap::system_message( SOCKCRT + string("localhost:") + tool::int2string(i_port) );
#ifdef NCURSES
-
- mvprintw( NCUR_PORT_X,NCUR_PORT_Y, "Port: %d ", i_port);
- refresh();
+ mvprintw( NCUR_PORT_X,NCUR_PORT_Y, "Port: %d ", i_port);
+ refresh();
#endif
- return i_sock;
+ return sock;
}
int
-sock::read_write( int* p_sock )
+sock::read_write( thrd* p_thrd, int i_sock )
{
- int i_sock = *p_sock;
- char c_req[READSOCK];
- int i_bytes = read(i_sock, c_req, READSOCK);
-
- if (i_bytes <= 0)
- {
- wrap::system_message( READERR );
- }
- else
- {
- // stores the request params.
- hashmap<string> map_params;
-
- // get the s_rep ( s_html response which will be send imediatly to the client
- struct sockaddr_in client;
- size_t size = sizeof(client);
-
-#ifdef CYGWIN
-
- getpeername( i_sock, (struct sockaddr *)&client, (int*)&size);
-#else
+ char c_req[READSOCK];
+ int i_bytes = read (i_sock, c_req, READSOCK);
- getpeername( i_sock, (struct sockaddr *)&client, &size);
-#endif
-
- map_params["REMOTE_ADDR"] = inet_ntoa(client.sin_addr);
- //map_params["REMOTE_PORT"] = ntohs(client.sin_port);
+ if (i_bytes <= 0)
+ {
+ wrap::system_message( READERR );
+ }
+ else
+ {
+ // stores the request params.
+ map_string map_params;
- string s_rep = req_parser->parse( i_sock, string( c_req ), map_params );
+ // get the s_rep ( s_html response which will be send imediatly to the client
+ struct sockaddr_in client;
+ size_t size = sizeof(client);
-#ifdef LOGGING
+ getpeername( i_sock, (struct sockaddr *)&client, &size);
- log_daemon->log_access(map_params);
-#endif
+ map_params["REMOTE_ADDR"] = inet_ntoa(client.sin_addr);
+ //map_params["REMOTE_PORT"] = ntohs(client.sin_port);
- // send s_rep to the client.
- send(i_sock, s_rep.c_str(), s_rep.size(), 0);
+ string s_rep = req_parser->parse( p_thrd, string( c_req ), map_params );
- // dont need those vals anymore.
- map_params.clear();
+ log_daemon->log_access(map_params);
- shutdown( i_sock, 2 );
- close ( i_sock );
+ // send s_rep to the client.
+ send( i_sock, s_rep.c_str(), s_rep.size(), 0 );
- return 0;
- }
+ // dont need those vals anymore.
+ map_params.clear();
- shutdown( i_sock, 2 );
- close ( i_sock );
+ return 0;
+ }
- return 1;
+ return -1;
}
int
sock::start()
{
- wrap::system_message( SOCKSRV );
+ wrap::system_message( SOCKSRV );
#ifdef NCURSES
-
- print_hits();
- thrd_pool->print_pool_size();
+ print_hits();
+ print_threads();
+ thrd_pool->print_pool_size();
#endif
- int i_port = tool::string2int( wrap::CONF->get_elem( "httpd.serverport" ) );
- int i_sock, i;
- fd_set active_fd_set, read_fd_set;
- struct sockaddr_in clientname;
- size_t size;
-
+ auto int i_port = tool::string2int( wrap::CONF->get_elem( "httpd.serverport" ) );
- // create the server socket and set it up to accept connections.
- i_sock = make_server_socket ( i_port );
+ int sock;
+ fd_set active_fd_set, read_fd_set;
+ int i;
+ struct sockaddr_in clientname;
+ size_t size;
- if (listen (i_sock, 1) < 0)
- {
- wrap::system_message( LISTERR );
- exit( EXIT_FAILURE );
- }
- wrap::system_message( SOCKRDY );
+ // create the server socket and set it up to accept connections.
+ sock = make_server_socket ( i_port );
- // initialize the set of active sockets.
- FD_ZERO (&active_fd_set);
- FD_SET (i_sock, &active_fd_set);
-
- while( b_run )
- {
- // block until input arrives on one or more active sockets.
- read_fd_set = active_fd_set;
- if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
+ if (listen (sock, 1) < 0)
{
- wrap::system_message( SELCERR );
-
+ wrap::system_message( LISTERR );
exit( EXIT_FAILURE );
}
- // service all the sockets with input pending.
- for ( i = 0; i < FD_SETSIZE; i++ )
- if ( FD_ISSET (i, &read_fd_set) )
- {
- if ( i == i_sock )
+ wrap::system_message( SOCKRDY );
+
+ // initialize the set of active sockets.
+ FD_ZERO (&active_fd_set);
+ FD_SET (sock, &active_fd_set);
+
+ while( b_run )
+ {
+ // block until input arrives on one or more active sockets.
+ read_fd_set = active_fd_set;
+ if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
{
- // connection request on original socket.
- ++i_req;
+ wrap::system_message( SELCERR );
-#ifdef NCURSES
+ exit( EXIT_FAILURE );
+ }
- print_hits();
+ // service all the sockets with input pending.
+ for ( i = 0; i < FD_SETSIZE; i++ )
+ if ( FD_ISSET (i, &read_fd_set) )
+ {
+ if ( i == sock )
+ {
+ // connection request on original socket.
+ i_req++;
+#ifdef NCURSES
+ print_hits();
#endif
+ int new_sock;
+ size = sizeof (clientname);
+ new_sock = accept (sock, (struct sockaddr *) &clientname, &size);
+
+ if (new_sock < 0)
+ {
+ wrap::system_message( ACCPERR );
+ close ( new_sock );
+ }
+
+ else
+ {
+#ifdef VERBOSE
+ wrap::system_message(NEWREQU
+ + tool::int2string(i_req) + " "
+ + string(inet_ntoa( clientname.sin_addr )) + ":"
+ + tool::int2string(ntohs ( clientname.sin_port ))
+ );
+#endif
+ FD_SET (new_sock, &active_fd_set);
+ }
+ }
+
+ else
+ {
+ thrd_pool->run( (void*) new thrd( i ) );
+ FD_CLR( i, &active_fd_set );
+ }
+ }
+ }
+}
- int i_new_sock;
- size = sizeof(clientname);
-#ifdef CYGWIN
-
- i_new_sock = accept (i_sock, (struct sockaddr *) &clientname, (int*)&size);
-#else
+void
+sock::increase_num_threads()
+{
+ pthread_mutex_lock( &mut_threads );
+ i_threads++;
+ pthread_mutex_unlock( &mut_threads );
- i_new_sock = accept (i_sock, (struct sockaddr *) &clientname, &size);
+#ifdef NCURSES
+ print_threads();
#endif
+}
- if (i_new_sock < 0)
- {
- wrap::system_message( ACCPERR );
- close(i_new_sock);
- }
- else
- {
-#ifdef VERBOSE
- wrap::system_message(NEWREQU
- + tool::int2string(i_req) + " "
- + string(inet_ntoa( clientname.sin_addr )) + ":"
- + tool::int2string(ntohs ( clientname.sin_port ))
- );
-#endif
+void
+sock::decrease_num_threads()
+{
+ pthread_mutex_lock( &mut_threads );
+ i_threads--;
+ pthread_mutex_unlock( &mut_threads );
- FD_SET (i_new_sock, &active_fd_set);
- }
- }
- else
- {
- int *p_sock = new int;
- *p_sock = i;
- thrd_pool->run( (void*) p_sock );
- FD_CLR( i, &active_fd_set );
- }
- }
- }
+#ifdef NCURSES
+ print_threads();
+#endif
}
#ifdef NCURSES
void
+sock::print_threads()
+{
+ if ( wrap::NCUR->is_ready() )
+ {
+ mvprintw( NCUR_POOL_RUNNING_X,NCUR_POOL_RUNNING_Y, "In use: %d ", i_threads);
+ refresh();
+ }
+}
+
+void
sock::print_hits()
{
- if ( wrap::NCUR->is_ready() )
- {
- mvprintw( NCUR_HITS_X,NCUR_HITS_Y, "Hits: %d ", i_req);
- refresh();
- }
+ if ( wrap::NCUR->is_ready() )
+ {
+ mvprintw( NCUR_HITS_X,NCUR_HITS_Y, "Hits: %d ", i_req);
+ refresh();
+ }
}
#endif
diff --git a/src/sock/sock.h b/src/sock/sock.h
index 0d93543..079dfd8 100755
--- a/src/sock/sock.h
+++ b/src/sock/sock.h
@@ -3,71 +3,65 @@
#ifndef SOCK_H
#define SOCK_H
+
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-
#include "../thrd/pool.h"
+#include "../thrd/thrd.h"
#include "../reqp.h"
-#include "../chat/user.h"
-
-#ifdef LOGGING
#include "../logd.h"
-#endif
-
-#include "../maps/hashmap.h"
using namespace std;
class sock
{
private:
- // total number of server requests.
- unsigned long long i_req;
-
- bool b_run; // true while socket manager is running.
- reqp *req_parser; // parses the http requests from clients.
- pool *thrd_pool; // the thread pool.
-#ifdef LOGGING
+ // total number of server requests.
+ unsigned long long int i_req;
- logd *log_daemon; // the log daemon
-#endif
+ bool b_run; // true while socket manager is running.
+ reqp* req_parser; // parses the http requests from clients.
+ pool* thrd_pool; // the thread pool.
+ logd* log_daemon; // the log daemon
+ char* c_buffer; // char buffer!
- char *c_buffer; // char buffer!
- int i_threads; // total amount of threads inside the thread pool.
+ int i_threads; // total amount of threads inside the thread pool.
+ pthread_mutex_t mut_threads;
+ pthread_mutex_t mut_hits;
- pthread_mutex_t mut_hits;
public:
- // creates a server socket.
- int make_server_socket( int i_port );
-
- // small inline methods:
- bool get_run() const
- {
- return b_run;
- }
-
- bool set_run( bool b_run )
- {
- this->b_run = b_run;
- }
-
- sock( );
- ~sock( );
-
- int read_write( int* p_sock );
- int start();
-
- // the chat stream there all the chat messages will sent through.
- static void chat_stream( int i_sock, user* p_user, hashmap<string> &map_params ); //<<
-
+ // creates a server socket.
+ int make_server_socket( int port );
+
+ // small inline methods:
+ bool get_run() const
+ {
+ return b_run;
+ }
+ bool set_run( bool b_run )
+ {
+ this->b_run = b_run;
+ }
+
+ // public methods.
+ explicit sock( ); // simple constructor.
+ ~sock( );
+ virtual int read_write( thrd* p_thrd, int filedes );
+ virtual int start();
+
+ // the chat stream there all the chat messages will sent through.
+
+ void increase_num_threads();
+ void decrease_num_threads();
#ifdef NCURSES
- void print_hits();
+ void print_threads();
+ void print_hits();
#endif
};
diff --git a/src/stats.cpp b/src/stats.cpp
index 4579f69..63757b6 100644
--- a/src/stats.cpp
+++ b/src/stats.cpp
@@ -8,144 +8,95 @@ using namespace std;
stats::stats()
{
- i_rusage_vec_size = tool::string2int(
- wrap::CONF->get_elem("httpd.stats.rusagehistory"));
+ i_rusage_vec_size = tool::string2int(
+ wrap::CONF->get_elem("httpd.stats.rusagehistory"));
- i_num_rooms = 0; //<<
- pthread_mutex_init( &mut_vec_rusage, NULL );
- pthread_mutex_init( &mut_num_rooms, NULL ); //<<
+ pthread_mutex_init( &mut_vec_rusage, NULL );
}
stats::~stats()
{
- pthread_mutex_destroy( &mut_vec_rusage );
- pthread_mutex_destroy( &mut_num_rooms ); //<<
+ pthread_mutex_destroy( &mut_vec_rusage );
}
void
stats::update_rusage_history()
{
- wrap::system_message(STATUPR);
-
- rusage* p_rusage = new rusage;
- getrusage( RUSAGE_SELF, p_rusage );
-
- map<string,long> map_rusage;
-
- map_rusage["ru_maxrss"] = p_rusage->ru_maxrss;
- map_rusage["ru_ixrss"] = p_rusage->ru_ixrss;
- map_rusage["ru_idrss"] = p_rusage->ru_idrss;
- map_rusage["ru_isrss"] = p_rusage->ru_isrss;
- map_rusage["ru_minflt"] = p_rusage->ru_minflt;
- map_rusage["ru_majflt"] = p_rusage->ru_majflt;
- map_rusage["ru_nswap"] = p_rusage->ru_nswap;
- map_rusage["ru_inblock"] = p_rusage->ru_inblock;
- map_rusage["ru_oublock"] = p_rusage->ru_oublock;
- map_rusage["ru_msgsnd"] = p_rusage->ru_msgsnd;
- map_rusage["ru_msgrcv"] = p_rusage->ru_msgrcv;
- map_rusage["ru_nsignals"] = p_rusage->ru_nsignals;
- map_rusage["ru_nvcsw"] = p_rusage->ru_nvcsw;
- map_rusage["ru_nivcsw"] = p_rusage->ru_nivcsw;
-
- delete p_rusage;
-
- pthread_mutex_lock ( &mut_vec_rusage );
-
- if ( vec_rusage_history.size() >= i_rusage_vec_size )
- vec_rusage_history.erase( vec_rusage_history.begin() );
-
- vec_rusage_history.push_back(map_rusage);
-
- pthread_mutex_unlock( &mut_vec_rusage );
+ wrap::system_message(STATUPR);
+
+ rusage* p_rusage = new rusage;
+ getrusage( RUSAGE_SELF, p_rusage );
+
+ map<string,long> map_rusage;
+
+ map_rusage["ru_maxrss"] = p_rusage->ru_maxrss;
+ map_rusage["ru_ixrss"] = p_rusage->ru_ixrss;
+ map_rusage["ru_idrss"] = p_rusage->ru_idrss;
+ map_rusage["ru_isrss"] = p_rusage->ru_isrss;
+ map_rusage["ru_minflt"] = p_rusage->ru_minflt;
+ map_rusage["ru_majflt"] = p_rusage->ru_majflt;
+ map_rusage["ru_nswap"] = p_rusage->ru_nswap;
+ map_rusage["ru_inblock"] = p_rusage->ru_inblock;
+ map_rusage["ru_oublock"] = p_rusage->ru_oublock;
+ map_rusage["ru_msgsnd"] = p_rusage->ru_msgsnd;
+ map_rusage["ru_msgrcv"] = p_rusage->ru_msgrcv;
+ map_rusage["ru_nsignals"] = p_rusage->ru_nsignals;
+ map_rusage["ru_nvcsw"] = p_rusage->ru_nvcsw;
+ map_rusage["ru_nivcsw"] = p_rusage->ru_nivcsw;
+
+ delete p_rusage;
+
+ pthread_mutex_lock ( &mut_vec_rusage );
+
+ if ( vec_rusage_history.size() >= i_rusage_vec_size )
+ vec_rusage_history.erase( vec_rusage_history.begin() );
+
+ vec_rusage_history.push_back(map_rusage);
+
+ pthread_mutex_unlock( &mut_vec_rusage );
}
void
stats::set_rusage_vec_size( int i_rusage_vec_size )
{
- pthread_mutex_lock ( &mut_vec_rusage );
- this->i_rusage_vec_size = i_rusage_vec_size;
- pthread_mutex_unlock( &mut_vec_rusage );
+ pthread_mutex_lock ( &mut_vec_rusage );
+ this->i_rusage_vec_size = i_rusage_vec_size;
+ pthread_mutex_unlock( &mut_vec_rusage );
}
long
stats::get_ru_maxrss()
{
- rusage* p_rusage = new rusage;
- getrusage( RUSAGE_SELF, p_rusage );
+ rusage* p_rusage = new rusage;
+ getrusage( RUSAGE_SELF, p_rusage );
- long l_ret = p_rusage->ru_maxrss;
- delete p_rusage;
+ long l_ret = p_rusage->ru_maxrss;
+ delete p_rusage;
- return l_ret;
+ return l_ret;
}
string
stats::get_rusage_history( string s_type, string s_seperator )
{
- string s_ret;
- int i_count = 0;
- vector< map<string,long> >::iterator iter;
-
- pthread_mutex_lock ( &mut_vec_rusage );
-
- for ( iter = vec_rusage_history.begin();
- iter != vec_rusage_history.end();
- iter++, i_count++ )
- s_ret.append(s_seperator +
- tool::int2string(i_count) + ". " + iter->find(s_type)->first + " " +
- tool::int2string( iter->find(s_type)->second) + "\n");
-
- pthread_mutex_unlock( &mut_vec_rusage );
-
- return s_ret;
-}
-
-//<<*
-int
-stats::get_num_rooms()
-{
- pthread_mutex_lock ( &mut_num_rooms );
- int i_ret = i_num_rooms;
- pthread_mutex_unlock( &mut_num_rooms );
- return i_ret;
-}
-
-void
-stats::increment_num_rooms()
-{
- pthread_mutex_lock ( &mut_num_rooms );
- ++i_num_rooms;
- pthread_mutex_unlock( &mut_num_rooms );
-#ifdef NCURSES
-
- print_num_rooms();
-#endif
-}
-void
-stats::decrement_num_rooms()
-{
- pthread_mutex_lock ( &mut_num_rooms );
- --i_num_rooms;
- pthread_mutex_unlock( &mut_num_rooms );
-#ifdef NCURSES
-
- print_num_rooms();
-#endif
-}
-
-#ifdef NCURSES
-void
-stats::print_num_rooms()
-{
- if ( !wrap::NCUR->is_ready() )
- return;
-
- mvprintw( NCUR_NUM_ROOMS_X, NCUR_NUM_ROOMS_Y, "Rooms: %d", get_num_rooms());
- refresh();
+ string s_ret;
+ int i_count = 0;
+ vector< map<string,long> >::iterator iter;
+
+ pthread_mutex_lock ( &mut_vec_rusage );
+
+ for ( iter = vec_rusage_history.begin();
+ iter != vec_rusage_history.end();
+ iter++, i_count++ )
+ s_ret.append(s_seperator +
+ tool::int2string(i_count) + ". " + iter->find(s_type)->first + " " +
+ tool::int2string( iter->find(s_type)->second) + "\n");
+
+ pthread_mutex_unlock( &mut_vec_rusage );
+
+ return s_ret;
}
-#endif
-//*>>
#endif
diff --git a/src/stats.h b/src/stats.h
index 4458b6a..0ef60a2 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -4,46 +4,33 @@
#define STATS_H
#include "tool/tool.h"
-
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <iostream>
using namespace std;
class stats
{
private:
- // Specifies the max. amount of elements in vec_rusage_history;
- int i_rusage_vec_size;
- // History of the last i_rusage_vec_size rusage values.
- vector< map<string,long> > vec_rusage_history;
- pthread_mutex_t mut_vec_rusage;
-
- int i_num_rooms; //<<
- pthread_mutex_t mut_num_rooms; //<<
+ // Specifies the max. amount of elements in vec_rusage_history;
+ int i_rusage_vec_size;
+ // History of the last i_rusage_vec_size rusage values.
+ vector< map<string,long> > vec_rusage_history;
+ pthread_mutex_t mut_vec_rusage;
- void set_rusage_vec_size( int i_rusage_vec_size );
+
+ void set_rusage_vec_size( int i_rusage_vec_size );
public:
- stats( );
+ stats( );
~stats( );
- //<<*
- int get_num_rooms();
- void increment_num_rooms();
- void decrement_num_rooms();
- //*>>
void update_rusage_history();
string get_rusage_history( string s_type, string s_seperator );
long get_ru_maxrss();
- //<<*
-#ifdef NCURSES
-
- void print_num_rooms();
-#endif
- //*>>
};
#endif
diff --git a/src/thrd/pool.cpp b/src/thrd/pool.cpp
index d25a873..1db639d 100755
--- a/src/thrd/pool.cpp
+++ b/src/thrd/pool.cpp
@@ -2,219 +2,204 @@
#define POOL_CPP
#include "pool.h"
+#include "thrd.h"
using namespace std;
-int pool::i_thrd_used = 0;
-
pool::pool()
{
- i_thrd_pool_size = tool::string2int( wrap::CONF->get_elem( "httpd.thread.initpoolsize" ) );
- i_thrd_pool_queue = tool::string2int( wrap::CONF->get_elem( "httpd.thread.queuesize" ) );
- tpool_init( &thread_pool, i_thrd_pool_size, i_thrd_pool_queue);
+ i_thrd_pool_size = tool::string2int( wrap::CONF->get_elem( "httpd.thread.poolsize" ) );
+ i_thrd_pool_queue = tool::string2int( wrap::CONF->get_elem( "httpd.thread.queuesize" ) );
+ tpool_init( &thread_pool, i_thrd_pool_size, i_thrd_pool_queue, 0 );
}
void
-pool::tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size)
+pool::tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full )
{
- int i, rtn;
- tpool_t tpool;
-
- // allocate a pool data structure
- if (( tpool = (tpool_t) malloc( sizeof( struct tpool ) ) ) == 0 )
- {
- wrap::system_message( POOLERR );
- exit(-1);
- }
-
- // initialize th fields
- tpool->num_threads = num_worker_threads;
- tpool->max_queue_size = max_queue_size;
-
- if ( ( tpool->threads = (pthread_t*) malloc( sizeof(pthread_t)*num_worker_threads ) ) == 0 )
- {
- wrap::system_message( POOLERR );
- exit(-1);
- }
-
- tpool->cur_queue_size = 0;
- tpool->queue_head = 0;
- tpool->queue_tail = 0;
-
- if ( ( rtn = pthread_mutex_init( &(tpool->queue_lock), 0 ) ) != 0 )
- {
- string s_err( "pthread_mutex_init " );
- s_err.append( strerror( rtn ) );
-
- wrap::system_message( s_err );
-
- exit(-1);
- }
- else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_empty), 0 ) ) != 0 )
- {
- string s_err( "pthread_cond_init (1): " );
- s_err.append( strerror( rtn ) );
-
- wrap::system_message( s_err );
-
- exit(1);
- }
- else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_full), 0 ) ) != 0 )
- {
- string s_err( "pthread_cond_init (2): " );
- s_err.append( strerror( rtn ) );
-
- wrap::system_message( s_err );
-
- exit(1);
- }
- else if ( ( rtn = pthread_cond_init( &(tpool->queue_empty), 0 ) ) != 0 )
- {
- string s_err( "pthread_mutex_init " );
- s_err.append( strerror( rtn ) );
-
- wrap::system_message( s_err );
-
- exit(1);
- }
-
- // create threads
- for ( i = 0; i < num_worker_threads; ++i )
- pthread_create( &(tpool->threads[i]) , 0, tpool_thread, (void*)tpool );
-
- *tpoolp = tpool;
-}
+ int i, rtn;
+ tpool_t tpool;
-void*
-pool::tpool_thread( void* p_void )
-{
- tpool_t tpool = (tpool_t) p_void;
- tpool_work_t *my_workp;
+ // allocate a pool data structure
+ if (( tpool = (tpool_t) malloc( sizeof( struct tpool ) ) ) == NULL )
+ {
+ wrap::system_message( POOLERR );
+ exit(-1);
+ }
- for( pthread_mutex_lock( &(tpool->queue_lock) );;
- pthread_mutex_lock( &(tpool->queue_lock) ), --i_thrd_used )
- {
+ // initialize th fields
+ tpool->num_threads = num_worker_threads;
+ tpool->max_queue_size = max_queue_size;
+ tpool->do_not_block_when_full = do_not_block_when_full;
-#ifdef NCURSES
- print_threads(i_thrd_used);
-#endif
+ if ( ( tpool->threads = (pthread_t*) malloc( sizeof( pthread_t ) *num_worker_threads ) ) == NULL )
+ {
+ wrap::system_message( POOLERR );
+ exit(-1);
+ }
- while (tpool->cur_queue_size == 0)
- pthread_cond_wait( &(tpool->queue_not_empty), &(tpool->queue_lock) );
+ tpool->cur_queue_size = 0;
+ tpool->queue_head = NULL;
+ tpool->queue_tail = NULL;
+ tpool->queue_closed = 0;
+ tpool->shutdown = 0;
- my_workp = tpool->queue_head;
- tpool->cur_queue_size--;
+ if ( ( rtn = pthread_mutex_init( &(tpool->queue_lock), NULL ) ) != 0 )
+ {
+ string s_err( "pthread_mutex_init " );
+ s_err.append( strerror( rtn ) );
- if ( tpool->cur_queue_size == 0)
- tpool->queue_head = tpool->queue_tail = 0;
+ wrap::system_message( s_err );
- else
- tpool->queue_head = my_workp->next;
+ exit(-1);
+ }
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_empty), NULL ) ) != 0 )
+ {
+ string s_err( "pthread_mutex_init " );
+ s_err.append( strerror( rtn ) );
+
+ wrap::system_message( s_err );
- if ( tpool->cur_queue_size == ( tpool->max_queue_size - 1 ) )
- pthread_cond_signal( &(tpool->queue_not_full) );
+ exit(-1);
+ }
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_not_full), NULL ) ) != 0 )
+ {
+ string s_err( "pthread_mutex_init " );
+ s_err.append( strerror( rtn ) );
- if ( tpool->cur_queue_size == 0 )
- pthread_cond_signal( &(tpool->queue_empty) );
+ wrap::system_message( s_err );
- pthread_mutex_unlock( &(tpool->queue_lock) );
+ exit(-1);
+ }
+ else if ( ( rtn = pthread_cond_init( &(tpool->queue_empty), NULL ) ) != 0 )
+ {
+ string s_err( "pthread_mutex_init " );
+ s_err.append( strerror( rtn ) );
- (*(my_workp->routine))(my_workp->p_void);
+ wrap::system_message( s_err );
- free(my_workp);
- }
-}
+ exit(-1);
+ }
+ // create threads
+ for ( i = 0; i < num_worker_threads; i++ )
+ pthread_create( &(tpool->threads[i]) , NULL, tpool_thread, (void*)tpool );
-void pool::run_func( void *p_void )
-{
- int* p_sock = (int*)p_void;
- wrap::SOCK->read_write( p_sock );
- delete p_sock;
+ *tpoolp = tpool;
}
-int
-pool::tpool_add_work( tpool_t tpool, void(*routine)(void*), void* p_void ) ///
+void*
+pool::tpool_thread( void* arg )
{
- tpool_work_t *workp;
- pthread_mutex_lock( &(tpool->queue_lock) );
+ tpool_t tpool = (tpool_t) arg;
+ tpool_work_t *my_workp;
- if ( ++i_thrd_used == tpool->num_threads )
- {
- int i_max_pool_size = tool::string2int( wrap::CONF->get_elem( "httpd.thread.maxpoolsize" ) );
- if ( i_max_pool_size != 0 && i_thrd_used > i_max_pool_size )
+ while( true )
{
- wrap::system_message(POOLER2+tool::int2string(i_thrd_used)+")");
- }
- else
- {
- int i_size = tpool->num_threads + 1;
+ pthread_mutex_lock( &(tpool->queue_lock) );
- wrap::system_message(POOLFLL+tool::int2string(i_size)+")");
+ while ( (tpool->cur_queue_size == 0) && (!tpool->shutdown) )
+ pthread_cond_wait( &(tpool->queue_not_empty), &(tpool->queue_lock) );
- tpool->threads = (pthread_t*)realloc((void*)tpool->threads, sizeof(pthread_t)*tpool->num_threads);
+ if (tpool->shutdown)
+ {
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ pthread_exit( NULL );
+ }
- for ( int i = tpool->num_threads; i < i_size; ++i )
- pthread_create( &(tpool->threads[i]) , 0, tpool_thread, (void*)tpool );
+ my_workp = tpool->queue_head;
+ tpool->cur_queue_size--;
- i_thrd_pool_size = tpool->num_threads = i_size;
-#ifdef NCURSES
+ if ( tpool->cur_queue_size == 0)
+ tpool->queue_head = tpool->queue_tail = NULL;
- print_pool_size();
-#endif
+ else
+ tpool->queue_head = my_workp->next;
- }
- }
+ if ( ( ! tpool->do_not_block_when_full ) &&
+ ( tpool->cur_queue_size == ( tpool->max_queue_size - 1 ) ) )
+ pthread_cond_signal( &(tpool->queue_not_full) );
-#ifdef NCURSES
- print_threads(i_thrd_used);
-#endif
+ if ( tpool->cur_queue_size == 0 )
+ pthread_cond_signal( &(tpool->queue_empty) );
+
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ (*(my_workp->routine))(my_workp->arg);
+ free((void*)my_workp);
+ }
+}
- while (tpool->cur_queue_size == tpool->max_queue_size)
- pthread_cond_wait( &(tpool->queue_not_full), &(tpool->queue_lock) );
+void pool::run_func( void *v_pointer )
+{
+ wrap::SOCK->increase_num_threads();
- // allocate work structure:
- workp = (tpool_work_t*) malloc( sizeof( tpool_work_t ) );
+ // recasting the client thread object.
+ thrd *t = (thrd*) v_pointer;
- workp->routine = routine;
- workp->p_void = p_void;
- workp->next = 0;
+ // start parsing the client request and sending response's back.
+ t-> run ();
- if (tpool->cur_queue_size == 0 )
- {
- tpool->queue_tail = tpool->queue_head = workp;
- }
- else
- {
- (tpool->queue_tail)->next = workp;
- tpool->queue_tail = workp;
- }
+ // close the client socket.
+ t->~thrd();
- tpool->cur_queue_size++;
- pthread_cond_signal( &tpool->queue_not_empty );
- pthread_mutex_unlock( &(tpool->queue_lock) );
+ wrap::SOCK->decrease_num_threads();
- return 0;
+ free(v_pointer);
}
-#ifdef NCURSES
-void
-pool::print_threads(int i_thrd_used)
+int
+pool::tpool_add_work( tpool_t tpool, void(*routine)(void*), void* arg ) ///
{
- if ( wrap::NCUR->is_ready() )
- {
- mvprintw( NCUR_POOL_RUNNING_X,NCUR_POOL_RUNNING_Y, "In use: %d ", i_thrd_used);
- refresh();
- }
+ tpool_work_t *workp;
+ pthread_mutex_lock( &(tpool->queue_lock) );
+
+ if( ( tpool->cur_queue_size == tpool->max_queue_size ) &&
+ tpool->do_not_block_when_full )
+ {
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ return -1;
+ }
+
+ while( ( tpool->cur_queue_size == tpool->max_queue_size ) &&
+ ( ! ( tpool->shutdown || tpool->queue_closed ) ) )
+ pthread_cond_wait( &(tpool->queue_not_full), &(tpool->queue_lock) );
+
+ if( tpool->shutdown || tpool->queue_closed )
+ {
+ pthread_mutex_unlock( &tpool->queue_lock );
+ return -1;
+ }
+
+ // allocate work structure:
+ workp = (tpool_work_t*) malloc( sizeof( tpool_work_t ) );
+
+ workp->routine = routine;
+ workp->arg = arg;
+ workp->next = NULL;
+
+ if( tpool->cur_queue_size == 0 )
+ {
+ tpool->queue_tail = tpool->queue_head = workp;
+ }
+ else
+ {
+ (tpool->queue_tail)->next = workp;
+ tpool->queue_tail = workp;
+ }
+
+ pthread_cond_signal( &tpool->queue_not_empty );
+ tpool->cur_queue_size++;
+ pthread_mutex_unlock( &(tpool->queue_lock) );
+ return 1;
}
+#ifdef NCURSES
void
pool::print_pool_size()
{
- if ( wrap::NCUR->is_ready() )
- {
- mvprintw( NCUR_POOL_SIZE_X,NCUR_POOL_SIZE_Y, "Size: %d %d", i_thrd_pool_size, i_thrd_pool_queue );
- refresh();
- }
+ if ( wrap::NCUR->is_ready() )
+ {
+ mvprintw( NCUR_POOL_SIZE_X,NCUR_POOL_SIZE_Y, "Size: %d %d", i_thrd_pool_size, i_thrd_pool_queue );
+ refresh();
+ }
}
#endif
diff --git a/src/thrd/pool.h b/src/thrd/pool.h
index 71ecaa9..a744133 100755
--- a/src/thrd/pool.h
+++ b/src/thrd/pool.h
@@ -8,60 +8,70 @@ using namespace std;
class pool
{
private:
- static int i_thrd_used;
-
- typedef struct tpool_work
- {
- void (*routine)(void*); ///
- void *p_void;
- struct tpool_work *next;
- }
- tpool_work_t;
-
- typedef struct tpool
- {
- // pool characteristics:
- int num_threads;
- int max_queue_size;
-
- // pool state
- pthread_t *threads;
- int cur_queue_size;
-
- tpool_work_t *queue_head;
- tpool_work_t *queue_tail;
-
- pthread_mutex_t queue_lock;
- pthread_cond_t queue_not_empty;
- pthread_cond_t queue_not_full;
- pthread_cond_t queue_empty;
- }
- *tpool_t;
-
- int i_thrd_pool_size;
- int i_thrd_pool_queue;
-
- tpool_t thread_pool;
-
- void tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size);
- int tpool_add_work( tpool_t tpool, void(*routine)(void*), void* p_void );
- static void* tpool_thread( void *p_void);
- static void run_func( void *p_void );
+ typedef struct tpool_work
+ {
+ void (*routine)(void*); ///
+ void *arg;
+ struct tpool_work *next;
+ }
+ tpool_work_t;
-public:
- pool();
+ typedef struct tpool
+ {
+ // pool characteristics:
+ int num_threads;
+ int max_queue_size;
+ int do_not_block_when_full;
+
+ // pool state
+ pthread_t *threads;
+ int cur_queue_size;
+
+ tpool_work_t *queue_head;
+ tpool_work_t *queue_tail;
+
+ pthread_mutex_t queue_lock;
+ pthread_cond_t queue_not_empty;
+ pthread_cond_t queue_not_full;
+ pthread_cond_t queue_empty;
+
+ int queue_closed;
+ int shutdown;
+ }
+ *tpool_t;
+
+ int i_thrd_pool_size;
+ int i_thrd_pool_queue;
+
+ tpool_t thread_pool;
- // inline (speed)!
- void run( void *p_void )
- {
- tpool_add_work( thread_pool, run_func, p_void );
- }
+ void
+ tpool_init( tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full );
+ int
+ tpool_add_work( tpool_t tpool, void(*routine)(void*), void* arg );
+
+ // virtual void
+ // tpool_destroy( tpool_t tpoolp, int finish );
+
+ static void*
+ tpool_thread( void* arg);
+
+ static void
+ run_func( void *v_pointer );
+
+ // public methods:
+public:
+ pool( );
+
+ // inline (speed)!
+ void run( void *arg )
+ {
+ tpool_add_work( thread_pool, run_func, arg );
+ }
#ifdef NCURSES
- void print_pool_size();
- static void print_threads(int i_thrd_used);
+ void print_pool_size();
#endif
-
};
#endif
diff --git a/src/thrd/thro.cpp b/src/thrd/thro.cpp
index e35520c..f6acf53 100644
--- a/src/thrd/thro.cpp
+++ b/src/thrd/thro.cpp
@@ -6,37 +6,40 @@
using namespace std;
thro::thro()
-{}
+{
+}
thro::~thro()
-{}
+{
+}
void
thro::run()
{
- void *p_void;
- run( p_void );
+ void* p_void;
+ run( p_void );
}
void
thro::run( void *p_void )
{
- elem.p_thro = this;
- elem.p_void = p_void;
- pthread_create( &pthread, NULL, start_, &elem );
+ elem.p_thro = this;
+ elem.p_void = p_void;
+ pthread_create( &pthread, NULL, start_, &elem );
}
void*
thro::start_( void *p_void )
{
- elements *e = (elements*) p_void;
- e->p_thro->start( e->p_void );
+ elements *e = (elements*) p_void;
+ e->p_thro->start( e->p_void );
}
void
thro::start( void *p_void )
{
- wrap::system_message( THRDSTR );
+ wrap::system_message( THRDSTR );
}
+
#endif
diff --git a/src/thrd/thro.h b/src/thrd/thro.h
index 783cd0d..ef38793 100644
--- a/src/thrd/thro.h
+++ b/src/thrd/thro.h
@@ -1,3 +1,5 @@
+// Threaded Object (thro)
+
#include "../incl.h"
#ifndef THRO_H
@@ -8,23 +10,21 @@ using namespace std;
class thro
{
private:
- pthread_t pthread;
+ pthread_t pthread;
- struct elements
- {
- thro *p_thro;
- void *p_void;
- }
- elem;
+ struct elements {
+ thro* p_thro;
+ void* p_void;
+ } elem;
- static void* start_( void *p_void );
+ static void* start_( void* p_void );
public:
- thro( );
- ~thro( );
- void run();
- void run( void *p_void );
- virtual void start( void *p_void );
+ thro( );
+ ~thro( );
+ void run();
+ void run( void* p_void );
+ virtual void start( void* p_void );
};
#endif
diff --git a/src/time/timo.cpp b/src/time/timo.cpp
index fd89bdf..c44ebae 100755
--- a/src/time/timo.cpp
+++ b/src/time/timo.cpp
@@ -7,32 +7,30 @@ using namespace std;
timo::timo()
{
- pthread_mutex_init( &mut_t_time, NULL );
+ pthread_mutex_init( &mut_t_time, NULL );
}
-
timo::~timo()
{
- pthread_mutex_destroy( &mut_t_time );
+ pthread_mutex_destroy( &mut_t_time );
}
double
timo::get_last_activity( )
{
- double d_ret;
-
- pthread_mutex_lock ( &mut_t_time );
- d_ret = wrap::TIMR->get_time_diff( t_time );
- pthread_mutex_unlock( &mut_t_time );
-
- return d_ret;
+ double d_ret;
+ pthread_mutex_lock ( &mut_t_time );
+ d_ret = wrap::TIMR->get_time_diff( t_time );
+ pthread_mutex_unlock( &mut_t_time );
+ return d_ret;
}
void
timo::renew_timeout( )
{
- pthread_mutex_lock ( &mut_t_time );
- time( &t_time );
- pthread_mutex_unlock( &mut_t_time );
+ pthread_mutex_lock ( &mut_t_time );
+ time( &t_time );
+ pthread_mutex_unlock( &mut_t_time );
}
+
#endif
diff --git a/src/time/timo.h b/src/time/timo.h
index 32268df..4eaecf8 100755
--- a/src/time/timo.h
+++ b/src/time/timo.h
@@ -8,15 +8,15 @@ using namespace std;
class timo // timeout class
{
protected:
- time_t t_time; // last activity time.
- pthread_mutex_t mut_t_time;
+ time_t t_time; // last activity time.
+ pthread_mutex_t mut_t_time;
public:
- timo( );
- ~timo( );
+ timo( );
+ ~timo( );
- double get_last_activity();
- void renew_timeout();
+ double get_last_activity();
+ void renew_timeout();
};
#endif
diff --git a/src/time/timr.cpp b/src/time/timr.cpp
index d2251d0..91dc7f7 100755
--- a/src/time/timr.cpp
+++ b/src/time/timr.cpp
@@ -10,14 +10,11 @@ timr::timr()
{
wrap::system_message( TIMERIN );
b_timer_active = true;
-
pthread_mutex_init( &mut_s_time, NULL);
pthread_mutex_init( &mut_s_uptime, NULL);
pthread_mutex_init( &mut_i_offset, NULL);
-
- i_time_offset = tool::string2int( wrap::CONF->get_elem("chat.timeoffset") );
+ i_time_offset = tool::string2int( wrap::CONF->get_elem("chat.timeoffset") );
wrap::system_message( TIMEROF + tool::int2string( i_time_offset ) );
-
s_time = "00:00:00";
s_uptime = "00:00:00";
}
@@ -32,106 +29,86 @@ timr::~timr()
bool
timr::get_timer_active() const
{
- return b_timer_active;
+ return b_timer_active;
}
int
-timr::get_offset()
+timr::get_offset()
{
- pthread_mutex_lock ( &mut_i_offset );
- int i_ret_val = i_time_offset;
- pthread_mutex_unlock( &mut_i_offset );
- return i_ret_val;
+ pthread_mutex_lock ( &mut_i_offset );
+ int i_ret_val = i_time_offset;
+ pthread_mutex_unlock( &mut_i_offset );
+ return i_ret_val;
}
void
-timr::start( void *v_ptr )
+timr::start( void *v_pointer )
{
- wrap::system_message( TIMERTH );
+// timr* p_timer = this; //static_cast<timr*>(this);
-#ifdef NCURSES
+ wrap::system_message( TIMERTH );
- print_time( );
+#ifdef NCURSES
+ print_time( );
#endif
- time_t clock_start;
- time_t clock_now;
-
- time( &clock_start );
- tm time_start = *localtime( &clock_start );
- tm time_now;
-
- while ( get_timer_active() )
- {
- // sleep a second!
- usleep( 1000000 );
+ time_t clock_start;
+ time_t clock_now;
- // get the current time!
- time( &clock_now );
+ time( &clock_start );
+ tm time_start = *localtime( &clock_start );
+ tm time_now;
+ while ( get_timer_active() )
+ {
+ // sleep a second!
+ usleep( 1000000 );
- time_now = *localtime( &clock_now );
+ // get the current time!
+ time( &clock_now );
- // set the current time && the current ychat uptime!
- set_time( difftime( clock_now, clock_start ),
- time_now.tm_sec, time_now.tm_min, time_now.tm_hour );
+ time_now = *localtime( &clock_now );
+ // set the current time && the current yhttpd uptime!
+ set_time( difftime( clock_now, clock_start ),
+ time_now.tm_sec, time_now.tm_min, time_now.tm_hour );
#ifdef NCURSES
-
- if (wrap::NCUR->is_ready())
+ if (wrap::NCUR->is_ready())
print_time( );
-#endif
-
- // run every minute:
- if ( time_now.tm_sec == 0 )
- {
+#endif
+ // run every minute:
+ if ( time_now.tm_sec == 0 )
+ {
#ifdef SERVMSG
cout << TIMERUP << get_uptime() << endl;
#endif
- //<<*
- int* p_timeout_settings = new int[3];
- p_timeout_settings[0] = tool::string2int(wrap::CONF->get_elem("chat.idle.timeout"));
- p_timeout_settings[1] = tool::string2int(wrap::CONF->get_elem("chat.idle.awaytimeout"));
- p_timeout_settings[2] = tool::string2int(wrap::CONF->get_elem("chat.idle.autoawaytimeout"));
- wrap::CHAT->check_timeout( p_timeout_settings );
- delete p_timeout_settings;
-
- string s_ping = "<!-- PING! //-->\n";
- wrap::CHAT->msg_post( &s_ping );
-
-#ifdef DATABASE
- // Disconnecting idle database conenction
- wrap::DATA->check_data_con_timeout();
-#endif
- //*>>
-
- // Run every ten minutes:
+
+ // run every ten minutes:
if ( time_now.tm_min % 10 == 0 )
{
- // Run every hour
- if ( time_now.tm_min % 60 == 0 )
- {
- wrap::GCOL->remove_garbage(); //<<
-
- // Run every day
- if (time_now.tm_min == 0 || time_now.tm_min == 60 )
- if (time_now.tm_hour == 0 || time_now.tm_hour == 24)
- wrap::STAT->update_rusage_history();
- }
+
+ // run every hour
+ if ( time_now.tm_hour % 60 == 0 )
+ {
+ // run every day
+ if (time_now.tm_min == 0 || time_now.tm_min == 60 )
+ if (time_now.tm_hour == 0 || time_now.tm_hour == 24)
+ wrap::STAT->update_rusage_history();
+ }
}
+ }
}
- }
}
#ifdef NCURSES
void
timr::print_time( )
{
- if ( !wrap::NCUR->is_ready() )
- return;
+ if ( !wrap::NCUR->is_ready() )
+ return;
- mvprintw( NCUR_TIME_X, NCUR_TIME_Y, "Time: %s ", get_time().c_str());
- mvprintw( NCUR_UPTIME_X, NCUR_UPTIME_Y, "Uptime: %s ", get_uptime().c_str());
- refresh();
+ mvprintw( NCUR_TIME_X, NCUR_TIME_Y, "Time: %s ", get_time().c_str());
+ mvprintw( NCUR_UPTIME_X, NCUR_UPTIME_Y, "Uptime: %s ", get_uptime().c_str());
+ refresh();
}
#endif
@@ -139,55 +116,52 @@ void
timr::set_time( double d_uptime, int i_cur_seconds, int i_cur_minutes, int i_cur_hours )
{
- int i_hours = (int) d_uptime / 3600;
- int i_minutes = (int) d_uptime / 60;
-
- while ( i_minutes >= 60 )
- i_minutes -= 60;
-
- while ( d_uptime >= 60 )
- d_uptime -= 60;
-
- // Calculate offset time
- i_cur_hours += get_offset();
-
- for ( int i = 24-i_cur_hours; i < 0; i = 24-i_cur_hours )
- i_cur_hours =- i;
-
- if (i_cur_hours == 24)
- i_cur_hours = 0;
-
- pthread_mutex_lock ( &mut_s_time );
- s_time = add_zero_to_front( tool::int2string( i_cur_hours ) ) + ":" +
- add_zero_to_front( tool::int2string( i_cur_minutes ) ) + ":" +
- add_zero_to_front( tool::int2string( i_cur_seconds ) );
- pthread_mutex_unlock( &mut_s_time );
-
- pthread_mutex_lock ( &mut_s_uptime );
- s_uptime = add_zero_to_front( tool::int2string( i_hours ) ) + ":" +
- add_zero_to_front( tool::int2string( i_minutes ) ) + ":" +
- add_zero_to_front( tool::int2string( (int) d_uptime ) );
- pthread_mutex_unlock( &mut_s_uptime );
+ int i_hours = (int) d_uptime / 3600;
+ int i_minutes = (int) d_uptime / 60;
+ while ( i_minutes >= 60 )
+ i_minutes -= 60;
+
+ while ( d_uptime >= 60 )
+ d_uptime -= 60;
+
+ // Calculate offset time
+ i_cur_hours += get_offset();
+ for (int i = 24 - i_cur_hours; i < 0; i = 24 - i_cur_hours)
+ i_cur_hours =- i;
+
+ if (i_cur_hours == 24)
+ i_cur_hours = 0;
+
+ pthread_mutex_lock ( &mut_s_time );
+ s_time = add_zero_to_front( tool::int2string( i_cur_hours ) ) + ":" +
+ add_zero_to_front( tool::int2string( i_cur_minutes ) ) + ":" +
+ add_zero_to_front( tool::int2string( i_cur_seconds ) );
+ pthread_mutex_unlock( &mut_s_time );
+
+ pthread_mutex_lock ( &mut_s_uptime );
+ s_uptime = add_zero_to_front( tool::int2string( i_hours ) ) + ":" +
+ add_zero_to_front( tool::int2string( i_minutes ) ) + ":" +
+ add_zero_to_front( tool::int2string( (int) d_uptime ) );
+ pthread_mutex_unlock( &mut_s_uptime );
}
string
timr::add_zero_to_front( string s_time )
{
- if ( s_time.length() == 1 )
- {
- string s_new = "0" + s_time;
- return s_new;
- }
+ if ( s_time.length() == 1 )
+ {
+ string s_new = "0" + s_time;
+ return s_new;
+ }
- return s_time;
+ return s_time;
}
double
-timr::get_time_diff( time_t &clock_diff )
+timr::get_time_diff( time_t& clock_diff )
{
- time_t clock_now;
- time( &clock_now );
-
- return difftime(clock_now, clock_diff);
+ time_t clock_now;
+ time( &clock_now );
+ return difftime( clock_now, clock_diff );
}
#endif
diff --git a/src/time/timr.h b/src/time/timr.h
index 12cdd8f..a327d5b 100755
--- a/src/time/timr.h
+++ b/src/time/timr.h
@@ -12,53 +12,52 @@ using namespace std;
class timr : public thro
{
private:
- bool b_timer_active;
- int i_time_offset;
- string s_uptime;
- string s_time;
-
- pthread_mutex_t mut_s_time;
- pthread_mutex_t mut_s_uptime;
- pthread_mutex_t mut_i_offset;
-
+ bool b_timer_active;
+ int i_time_offset;
+ string s_uptime;
+ string s_time;
+
+ pthread_mutex_t mut_s_time;
+ pthread_mutex_t mut_s_uptime;
+ pthread_mutex_t mut_i_offset;
+
public:
- timr();
- ~timr();
+ timr();
+ ~timr();
- bool get_timer_active() const;
- void start( void *v_ptr );
+ bool get_timer_active() const;
+ void start( void *v_pointer );
#ifdef NCURSES
-
- void print_time();
+ void print_time( );
#endif
- void set_time( double d_uptime, int i_cur_seconds, int i_cur_minutes, int i_cur_hours );
- string add_zero_to_front( string s_time );
-
- // inline for dynamic module access!
- string
- get_time( )
- {
- string s_ret;
- pthread_mutex_lock ( &mut_s_time );
- s_ret = this->s_time;
- pthread_mutex_unlock( &mut_s_time );
- return s_ret;
- }
-
- string
- get_uptime( )
- {
- string s_ret;
- pthread_mutex_lock ( &mut_s_uptime );
- s_ret = this->s_uptime;
- pthread_mutex_unlock( &mut_s_uptime );
- return s_ret;
- }
-
- int get_offset();
- double get_time_diff( time_t &clock_diff );
+ void set_time( double d_uptime, int i_cur_seconds, int i_cur_minutes, int i_cur_hours );
+ string add_zero_to_front( string s_time );
+
+ // inline for dynamic module access!
+ string
+ get_time( )
+ {
+ string s_ret;
+ pthread_mutex_lock ( &mut_s_time );
+ s_ret = this->s_time;
+ pthread_mutex_unlock( &mut_s_time );
+ return s_ret;
+ }
+
+ string
+ get_uptime( )
+ {
+ string s_ret;
+ pthread_mutex_lock ( &mut_s_uptime );
+ s_ret = this->s_uptime;
+ pthread_mutex_unlock( &mut_s_uptime );
+ return s_ret;
+ }
+
+ virtual int get_offset();
+ virtual double get_time_diff( time_t& clock_diff );
};
#endif
diff --git a/src/tool/dir.cpp b/src/tool/dir.cpp
index a23cca2..392112a 100644
--- a/src/tool/dir.cpp
+++ b/src/tool/dir.cpp
@@ -7,60 +7,60 @@ using namespace std;
dir::dir()
{
- b_open = false;
+ b_open = false;
}
dir::~dir()
{
- vec_dir.clear();
- close_dir();
+ dir_vec.clear();
+ close_dir();
}
bool
dir::open_dir( char *c_dir )
{
- string s_dir( c_dir );
- return open_dir( s_dir );
+ string s_dir( c_dir );
+ return open_dir( s_dir );
}
bool
dir::open_dir( string &s_dir )
{
- if ( b_open )
- return false;
+ if ( b_open )
+ return false;
- p_d = opendir( s_dir.c_str() );
+ dp = opendir( s_dir.c_str() );
- if ( p_d == NULL )
- return false; // Could not open dir.
+ if ( dp == NULL )
+ return false; // Could not open dir.
- b_open = true;
+ b_open = true;
- return true; // Could open dir with success.
+ return true; // Could open dir with success.
}
void
dir::close_dir()
{
- if ( b_open && p_d != NULL )
- {
- closedir( p_d );
- b_open = false;
- }
+ if ( b_open && dp != NULL )
+ {
+ closedir( dp );
+ b_open = false;
+ }
}
void
dir::read_dir()
{
- if ( p_d != NULL )
- while( p_ep = readdir( p_d ) )
- vec_dir.push_back( string( p_ep->d_name ) );
+ if ( dp != NULL )
+ while( ep = readdir( dp ) )
+ dir_vec.push_back( string( ep->d_name ) );
}
-vector<string>
+vector<string>
dir::get_dir_vec()
{
- return vec_dir;
+ return dir_vec;
}
#endif
diff --git a/src/tool/dir.h b/src/tool/dir.h
index eea78f7..cff265f 100644
--- a/src/tool/dir.h
+++ b/src/tool/dir.h
@@ -6,9 +6,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
-
#include <vector>
-
#include "../incl.h"
using namespace std;
@@ -16,20 +14,20 @@ using namespace std;
class dir
{
private:
- bool b_open;
- DIR *p_d;
- struct dirent *p_ep;
- vector<string> vec_dir;
+ bool b_open;
+ DIR *dp;
+ struct dirent *ep;
+ vector<string> dir_vec;
public:
- dir();
- ~dir();
-
- bool open_dir( char *c_dir );
- bool open_dir( string &s_dir );
- void close_dir();
- void read_dir();
- vector<string> get_dir_vec();
+ dir();
+ ~dir();
+
+ bool open_dir( char *c_dir );
+ bool open_dir( string &s_dir );
+ void close_dir();
+ void read_dir();
+ vector<string> get_dir_vec();
};
#endif
diff --git a/src/tool/tool.cpp b/src/tool/tool.cpp
index 3b8e326..1da4a12 100644
--- a/src/tool/tool.cpp
+++ b/src/tool/tool.cpp
@@ -11,229 +11,118 @@
#include "tool.h"
-bool
-tool::is_alpha_numeric( string &s_digit )
-{
- const char *p_digit = s_digit.c_str();
- int i_len = strlen( p_digit );
-
- for( int i=0; i<i_len; i++ )
- {
- if ( ! isalnum( *p_digit ) )
- return false;
- p_digit++;
- }
-
- return true;
-}
-
-string
-tool::int2string( int i_int )
-{
- char buf[64];
- sprintf(buf, "%d", i_int);
- return buf;
-}
-
-long
-tool::unixtime()
-{
- time_t clock;
- return (long) time( &clock );
-}
-
-int
-tool::string2int( string s_digit )
-{
- const char *p_digit = s_digit.c_str();
- int i_res = 0;
-
- // Convert each digit char and add into result.
- while (*p_digit >= '0' && *p_digit <='9')
- {
- i_res = (i_res * 10) + (*p_digit - '0');
- p_digit++;
- }
-
- // Check that there were no non-digits at end.
- if (*p_digit != 0)
- {
- return -1;
- }
-
- return i_res;
-}
-
-string
-tool::to_lower( string s_str )
-{
- string s_tmp("");
-
- for( int i = 0; i < s_str.size() ;i++ )
- s_tmp = s_tmp + (char) tolower( s_str.at(i) );
-
- return s_tmp;
-}
-
-void
-tool::strip_html( string *p_str)
-{
- int i_pos;
-
- if( (i_pos=p_str->find("<", 0)) == string::npos )
- return;
-
- while(true)
- {
- p_str->replace(i_pos, 1, "&lt;");
-
- if( (i_pos = p_str->find("<", 0)) == string::npos )
- return;
- }
-}
-
-string
-tool::ychat_version()
-{
- return "yChat " + string(VERSION)
- + "-" + string(BRANCH)
- + " Build " + int2string(BUILDNR);
-}
-
-list<string>
-tool::split_string(string s_string, string s_split)
-{
- list<string> list_ret;
- unsigned i_pos, i_len = s_split.length();
-
- while ( (i_pos = s_string.find(s_split)) != string::npos )
- {
- list_ret.push_back( s_string.substr(0, i_pos) );
- s_string = s_string.substr( i_pos + i_len );
- }
-
- list_ret.push_back( s_string );
-
- return list_ret;
-}
-
string
tool::trim( string s_str )
{
- if( s_str.empty() )
- return s_str;
+ if(s_str.empty())
+ return "";
- char c_cur = s_str[0];
- int i_pos = 0;
+ char c_cur = s_str[0];
+ auto int pos=0;
- // left trim
- while ( c_cur == ' '|| c_cur == '\n' || c_cur == '\r' )
- {
- s_str.erase(i_pos,1);
- c_cur = s_str[++i_pos];
- }
+ // left trim
+ while (c_cur==' '|| c_cur == '\n' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+ c_cur = s_str[++pos];
+ }
- // right trim
- i_pos = s_str.size();
- c_cur = s_str[s_str.size()];
+ // right trim
+ pos=s_str.size();
+ c_cur = s_str[s_str.size()];
- while ( c_cur == ' ' || c_cur == '\n' || c_cur == '\0' || c_cur == '\r' )
- {
- s_str.erase(i_pos, 1);
- c_cur = s_str[--i_pos];
- }
+ while (c_cur==' ' || c_cur == '\n' || c_cur == '\0' || c_cur == '\r')
+ {
+ s_str.erase(pos,1);
+ c_cur = s_str[--pos];
+ }
- return s_str;
+ return s_str;
}
char*
tool::clean_char( char* c_str )
{
// Ralf:
- for ( char* c_pos = c_str; *c_pos != '\0'; ++c_pos )
- if ( iscntrl(*c_pos) )
- *c_pos = ' ';
-
+ char *c_pos;
+ for (c_pos = c_str; *c_pos != '\0'; ++c_pos)
+ if ( iscntrl(*c_pos) ) *c_pos = ' ';
return c_str;
}
string
tool::replace( string s_string, string s_search, string s_replace )
{
- unsigned i_pos[2];
+ unsigned int i_pos[2];
- for ( i_pos[0] = s_string.find( s_search );
- i_pos[0] != string::npos;
- i_pos[0] = s_string.find( s_search, i_pos[1] ) )
- {
- s_string.replace( i_pos[0], s_search.length(), s_replace );
- i_pos[1] = i_pos[0] + s_replace.length();
- }
+ for ( i_pos[0] = s_string.find( s_search );
+ i_pos[0] != string::npos;
+ i_pos[0] = s_string.find( s_search, i_pos[1] ) )
+ {
+ s_string.replace( i_pos[0], s_search.length(), s_replace );
+ i_pos[1] = i_pos[0] + s_replace.length();
+ }
- return s_string;
+ return s_string;
}
string
tool::get_extension( string s_file )
{
- int i_pos = s_file.find_last_of(".");
-
- if( i_pos != string::npos )
- {
- string s_ext = s_file.substr(i_pos+1, s_file.size()-i_pos-1 );
- for( int i = 0; i < s_ext.size(); ++i )
- s_ext[i] = tolower(s_ext[i]);
-
- return to_lower(s_ext);
- }
+ int pos = s_file.find_last_of(".");
+ if(pos != string::npos)
+ {
+ string s_ext=s_file.substr(pos+1, s_file.size()-(pos+1));
+ for(int i = 0;i<s_ext.size();i++)
+ s_ext[i]=tolower(s_ext[i]);
- return "";
+ return to_lower(s_ext);
+ }
+ return "";
}
char*
tool::int2char( int i_int )
{
- char *buf = new char[64];
- sprintf(buf, "%d", i_int);
- return buf;
+ char *buffer = new char[64];
+ sprintf(buffer, "%d", i_int);
+ return buffer;
}
string
tool::shell_command( string s_command, method m_method )
{
- FILE *file;
- char buf[READBUF];
- char *c_pos;
- string s_ret = "";
-
- wrap::system_message(SHELLEX);
- wrap::system_message(s_command);
-
- if( (file=popen(s_command.c_str(), "r")) == NULL )
- {
- wrap::system_message( SHELLER );
- }
- else
- {
- while(true)
+ FILE *file;
+ char buffer[READBUF];
+ char* c_pos;
+ string s_ret = "";
+
+ wrap::system_message(SHELLEX);
+ wrap::system_message(s_command);
+
+ if( (file=popen(s_command.c_str(), "r")) == NULL )
{
- if(fgets(buf, READBUF, file) == NULL)
- break;
-
- switch (m_method)
- {
- case METH_NCURSES:
- wrap::system_message( clean_char(buf) );
- break;
- default:
- s_ret.append("\n" + string(buf));
- } // switch
+ wrap::system_message( SHELLER );
}
- pclose(file);
- }
+ else
+ {
+ while(true)
+ {
+ if(fgets(buffer, READBUF, file) == NULL)
+ break;
+ switch (m_method) {
+ case METH_NCURSES:
+ wrap::system_message( clean_char(buffer) );
+ break;
+ default:
+ s_ret.append("\n" + string(buffer));
+ } // switch
+ }
+ pclose(file);
+ }
- return s_ret;
+ return s_ret;
}
#endif
diff --git a/src/tool/tool.h b/src/tool/tool.h
index e0dea50..a350c69 100644
--- a/src/tool/tool.h
+++ b/src/tool/tool.h
@@ -3,27 +3,91 @@
#include "../incl.h"
-#include <list>
-
using namespace std;
class tool
{
public:
- static list<string> split_string(string s_string, string s_split);
- static bool is_alpha_numeric( string &s_digit );
- static char* int2char( int i_int );
- static char* clean_char( char* c_str);
- static string trim( string s_str );
- static string replace( string s_string, string s_search, string s_replace );
- static string int2string( int i_int );
- static long unixtime();
- static int string2int( string s_digit );
- static string get_extension( string s_file );
- static string to_lower( string s_str );
- static void strip_html( string *p_str );
- static string shell_command( string s_command, method m_method );
- static string ychat_version();
+ static bool is_alpha_numeric( string &s_digit )
+ {
+ auto const char *digit = s_digit.c_str();
+ auto int i_len = strlen( digit );
+
+
+ for( int i=0; i<i_len; i++ )
+ {
+ if ( ! isalnum( *digit ) )
+ return false;
+ digit++;
+ }
+ return true;
+ }
+
+ static char* int2char( int i_int );
+ static char* clean_char( char* c_str);
+ static string trim( string s_str );
+ static string replace( string s_string, string s_search, string s_replace );
+ static string int2string( int i_int )
+ {
+ char buffer[64];
+ sprintf(buffer, "%d", i_int);
+ return string(buffer);
+ }
+
+ static long unixtime()
+ {
+ time_t clock;
+ return (long) time( &clock );
+ }
+
+ static int string2int( string s_digit )
+ {
+ auto const char *digit = s_digit.c_str();
+ int result = 0;
+
+ // Convert each digit char and add into result.
+ while (*digit >= '0' && *digit <='9')
+ {
+ result = (result * 10) + (*digit - '0');
+ digit++;
+ }
+
+ // Check that there were no non-digits at end.
+ if (*digit != 0)
+ {
+ return -1;
+ }
+
+ return result;
+ }
+ static void strip_html( string *s_str)
+ {
+ auto int i_pos;
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+ while(true)
+ {
+ s_str->replace(i_pos,1,"&lt;");
+ if((i_pos=s_str->find("<",0))==string::npos)
+ return;
+ }
+ }
+
+ static string get_extension( string s_file );
+ static string to_lower( string s )
+ {
+ string s_tmp("");
+ for(int i=0;i < s.size() ;i++)
+ s_tmp=s_tmp+(char)tolower(s.at(i));
+ return s_tmp;
+ }
+
+ static string shell_command( string s_command, method m_method );
+
+ static string yhttpd_version()
+ {
+ return string(VERSION) + "-" + string(BRANCH) + " Build " + int2string(BUILDNR);
+ }
};
#endif
diff --git a/src/wrap.cpp b/src/wrap.cpp
index 715ce56..81c6679 100755
--- a/src/wrap.cpp
+++ b/src/wrap.cpp
@@ -5,21 +5,11 @@
using namespace std;
-//<<*
-chat* wrap::CHAT;
-#ifdef DATABASE
-data* wrap::DATA;
-#endif
-gcol* wrap::GCOL;
-sman* wrap::SMAN;
-modl* wrap::MODL;
-//*>>
conf* wrap::CONF;
html* wrap::HTML;
-#ifdef LOGGING
logd* wrap::LOGD;
-#endif
+modl* wrap::MODL;
#ifdef NCURSES
ncur* wrap::NCUR;
#endif
@@ -32,15 +22,11 @@ void
wrap::system_message( string s_message )
{
#ifdef NCURSES
- wrap::NCUR->print( s_message );
+ wrap::NCUR->print( s_message );
#endif
#ifdef SERVMSG
-
- cout << s_message << endl;
-#endif
-#ifdef LOGGING
-
- wrap::LOGD->log_simple_line( s_message + "\n" );
+ cout << s_message << endl;
#endif
+ wrap::LOGD->log_simple_line( s_message + "\n" );
}
#endif
diff --git a/src/wrap.h b/src/wrap.h
index 4968ae1..1207f03 100755
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -2,107 +2,66 @@
#define WRAP_H
#include "incl.h"
+
#ifdef DATABASE
-#include "data/data.h"
#endif
-#include "chat/chat.h"
#include "conf/conf.h"
-#include "chat/gcol.h"
#include "html.h"
-#ifdef LOGGING
#include "logd.h"
-#endif
-//<<*
#include "modl.h"
-//*>>
#ifdef NCURSES
#include "ncur/ncur.h"
#endif
-#include "chat/sman.h"
#include "sock/sock.h"
#include "stats.h"
#include "time/timr.h"
using namespace std;
-class dynamic_wrap
+class dynamic_wrap
{
-public:
- //<<*
- chat* CHAT;
-#ifdef DATABASE
-
- data* DATA;
-#endif
+ public:
- gcol* GCOL;
- sman* SMAN;
- modl* MODL;
- //*>>
-
- conf* CONF;
- html* HTML;
-#ifdef LOGGING
-
- logd* LOGD;
-#endif
+ conf* CONF;
+ html* HTML;
+ logd* LOGD;
+ modl* MODL;
#ifdef NCURSES
-
- ncur* NCUR;
+ ncur* NCUR;
#endif
-
- sock* SOCK;
- stats* STAT;
- timr* TIMR;
+ sock* SOCK;
+ stats* STAT;
+ timr* TIMR;
};
class wrap
{
public:
- static void system_message( char* c_message )
- {
- wrap::system_message( string(c_message) );
- }
+ static void system_message( char* c_message )
+ {
+ wrap::system_message( string(c_message) );
+ }
- static void system_message( string* p_message )
- {
- wrap::system_message( *p_message );
- }
+ static void system_message( string* p_message )
+ {
+ wrap::system_message( *p_message );
+ }
- static void system_message( string s_message );
+ static void system_message( string s_message );
- //<<*
- static chat* CHAT;
-#ifdef DATABASE
- static data* DATA;
-#endif
-
- static gcol* GCOL;
- static sman* SMAN;
-#ifdef IRCBOT
-
- static ybot* YBOT;
-#endif
-
- static modl* MODL;
- //*>>
-
- static conf* CONF;
- static html* HTML;
-#ifdef LOGGING
-
- static logd* LOGD;
-#endif
+ static conf* CONF;
+ static html* HTML;
+ static logd* LOGD;
+ static modl* MODL;
#ifdef NCURSES
-
- static ncur* NCUR;
+ static ncur* NCUR;
#endif
-
- static sock* SOCK;
- static stats* STAT;
- static timr* TIMR;
- static dynamic_wrap* WRAP;
+ static sock* SOCK;
+ static stats* STAT;
+ static timr* TIMR;
+ static dynamic_wrap* WRAP;
};
+
#endif