explorer: merge changes of audited repository

------------------------------------------------------------------------
r115 | martinf | 2006-02-15 20:35:08 +0100 (Mi, 15 Feb 2006) | 1 line

explorer: beginnings of bengali translation (not yet integrated into the compile process)
------------------------------------------------------------------------
r107 | martinf | 2006-02-12 11:35:41 +0100 (So, 12 Feb 2006) | 1 line

XMLStorage update to prepare for rbuild integration
------------------------------------------------------------------------
r72 | martinf | 2006-02-02 21:20:51 +0100 (Do, 02 Feb 2006) | 1 line

convert *.rbuild files into valid XML files by inserting XML headers and a <rbuild> root nodes
------------------------------------------------------------------------
r56 | martinf | 2006-01-30 22:37:09 +0100 (Mo, 30 Jan 2006) | 1 line

Explorer: eliminate compiler warning
------------------------------------------------------------------------
r36 | martinf | 2006-01-29 16:59:25 +0100 (So, 29 Jan 2006) | 1 line

Explorer: fix Rebar resizing
------------------------------------------------------------------------
r35 | martinf | 2006-01-29 16:28:15 +0100 (So, 29 Jan 2006) | 1 line

explorer: add icon cache mapped by shell paths (PIDLs) to fix GDI handle leaks

svn path=/trunk/; revision=21178
This commit is contained in:
Martin Fuchs 2006-02-21 20:55:41 +00:00
parent 3f9e9357c2
commit d96ff76bd5
22 changed files with 1160 additions and 473 deletions

View file

@ -1,7 +1,7 @@
#
# ReactOS shell
#
# Makefile.PCH
# Makefile-rosshell-MinGW
#
# MinGW Makefile with precompiled header support
#

View file

@ -1,100 +0,0 @@
#
# ReactOS explorer
#
# Makefile.PCH
#
# MinGW Makefile with precompiled header support
#
CC = gcc
CXX = g++
LINK = g++
CFLAGS = -DWIN32 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 -fexceptions -Wall -I. -I$(EXPAT_INC)
RCFLAGS = -DWIN32 -D__WINDRES__
LFLAGS = -Wl,--subsystem,windows
ifdef DEBUG
CFLAGS += -D_DEBUG -g
RCFLAGS += -D_DEBUG
LFLAGS += -g
else
CFLAGS += -DNDEBUG -Os #-march=pentium4
RCFLAGS += -DNDEBUG
LFLAGS += -s
endif
ifndef UNICODE
UNICODE = 1
endif
ifeq ($(UNICODE),1)
CFLAGS += -DUNICODE
# LFLAGS+= -Wl,--entry,_wWinMain@16
RCFLAGS += -DUNICODE
endif
CXXFLAGS = $(CFLAGS)
EXEC_SUFFIX = .exe
RES_SUFFIX = .coff
VPATH = shell utility taskbar desktop dialogs services
PROGRAM = explorer
TARGET = $(PROGRAM)$(EXEC_SUFFIX)
OBJECTS = \
startup.o \
shellclasses.o \
utility.o \
window.o \
dragdropimpl.o \
shellbrowserimpl.o \
shellservices.o \
explorer.o \
entries.o \
winfs.o \
unixfs.o \
shellfs.o \
ntobjfs.o \
regfs.o \
fatfs.o \
webchild.o \
mainframe.o \
filechild.o \
pane.o \
shellbrowser.o \
desktop.o \
desktopbar.o \
taskbar.o \
startmenu.o \
traynotify.o \
quicklaunch.o \
favorites.o \
searchprogram.o \
settings.o \
i386-stub-win32.o \
xmlstorage.o
LIBS = gdi32 comctl32 msimg32 ole32 uuid
DELAYIMPORTS = oleaut32 wsock32
all: precomp.h.gch $(TARGET)
precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h
$(CXX) $(CFLAGS) precomp.h
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
$(PROGRAM)$(RES_SUFFIX): explorer_intres.rc res/*.bmp res/*.ico
windres $(RCFLAGS) -o $@ explorer_intres.rc
notifyhook.dll: notifyhook/notifyhook.c notifyhook/notifyhook.h
$(CC) -D_WIN32_IE=0x0600 -Wall -D_NOTIFYHOOK_IMPL -Os -s notifyhook/notifyhook.c -shared -o $@
clean:
rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) precomp.h.gch \
desktop/*.o dialogs/*.o shell/*.o taskbar/*.o utility/*.o

View file

@ -0,0 +1,396 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDM_MDIFRAME MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Execute...", ID_EXECUTE
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "&Extra Bar", ID_VIEW_EXTRA_BAR
MENUITEM "&Drivebar", ID_VIEW_DRIVE_BAR, CHECKED
MENUITEM "S&ide Bar", ID_VIEW_SIDE_BAR
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "SDI", ID_VIEW_SDI
END
POPUP "&Window"
BEGIN
MENUITEM "New &Window", ID_WINDOW_NEW
MENUITEM "Cascading\tShift+F5", ID_WINDOW_CASCADE
MENUITEM "Tile &Horizontally", ID_WINDOW_TILE_HORZ
MENUITEM "Tile &Vertically\tShift+F4", ID_WINDOW_TILE_VERT
MENUITEM "Arrange Automatically", ID_WINDOW_AUTOSORT
MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Help"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER
MENUITEM "About &OS...", ID_ABOUT_WINDOWS
END
END
IDM_DESKTOPBAR MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Settings...", ID_DESKTOPBAR_SETTINGS
MENUITEM "&Task Manager...", ID_TASKMGR
MENUITEM SEPARATOR
MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER
END
END
IDM_VOLUME MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "Open Volume Control", ID_TRAY_VOLUME
MENUITEM "Adjust Audio Properties", ID_VOLUME_PROPERTIES
END
END
IDM_NOTIFYAREA MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Show hidden icons", ID_SHOW_HIDDEN_ICONS
MENUITEM "Show Icon &Button", ID_SHOW_ICON_BUTTON
MENUITEM "&Configure Notifications...", ID_CONFIG_NOTIFYAREA
MENUITEM "Adjust Date/&Time...", ID_CONFIG_TIME
MENUITEM SEPARATOR
MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER
END
END
IDM_SDIFRAME MENU DISCARDABLE
BEGIN
POPUP "&ev·"
BEGIN
MENUITEM "&cwiPvjbv...", ID_EXECUTE
MENUITEM SEPARATOR
MENUITEM "&eÜ Kiv", ID_FILE_EXIT
END
POPUP "&cÖ`k©b"
BEGIN
MENUITEM "&mnvqK ev·", ID_VIEW_TOOL_BAR
MENUITEM "cvk¦© ev·", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Ae¯v wb‡`©kK ev·", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&cyY:m‡ZR Kiv", ID_REFRESH
MENUITEM "m¤ú~Y© c`©vq", ID_VIEW_FULLSCREEN
MENUITEM "&eûgyLx Kg©‡¶Î", ID_VIEW_MDI
END
POPUP "&mnvqK"
BEGIN
MENUITEM "&wba©vib", ID_TOOLS_OPTIONS
END
POPUP "&mvnvh¨"
BEGIN
MENUITEM "&we¯—viK m¤ú©‡K...", ID_ABOUT_EXPLORER
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_EXECUTE DIALOG DISCARDABLE 15, 13, 210, 63
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Execute"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,150,10
CONTROL "&Command:",-1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,3,
18,60,10
EDITTEXT 201,3,29,134,12,ES_AUTOHSCROLL
CONTROL "As &Symbol",214,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,
45,71,12
DEFPUSHBUTTON "&OK",1,158,6,47,14
PUSHBUTTON "&Cancel",2,158,23,47,14
PUSHBUTTON "&Help",254,158,43,47,14
END
IDD_SEARCH_PROGRAM DIALOGEX 0, 0, 200, 65
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Search Program in Startmenu"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
LTEXT "&Filter:",IDC_STATIC,7,9,18,8
EDITTEXT IDC_FILTER,34,7,100,14,ES_AUTOHSCROLL
CONTROL "List1",IDC_PROGRAMS_FOUND,"SysListView32",LVS_REPORT |
LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER |
WS_TABSTOP,7,25,186,33
PUSHBUTTON "&Check Entries",IDC_CHECK_ENTRIES,143,7,50,14
END
IDD_DESKBAR_DESKTOP DIALOG DISCARDABLE 0, 0, 212, 194
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Desktop Properties"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Please select your prefered icon alignment algorithm:",
IDC_STATIC,7,7,166,8
CONTROL "left/top dwn",IDC_ICON_ALIGN_0,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,7,25,46,44
CONTROL "left/top right",IDC_ICON_ALIGN_1,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,57,25,46,44
CONTROL "right/top left",IDC_ICON_ALIGN_2,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,110,25,46,44
CONTROL "rig./top dwn",IDC_ICON_ALIGN_3,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,159,25,46,44
CONTROL "left/bot. up",IDC_ICON_ALIGN_4,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,7,73,46,44
CONTROL "left/bot. right",IDC_ICON_ALIGN_5,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,57,73,46,44
CONTROL "right/bot. left",IDC_ICON_ALIGN_6,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,110,73,46,44
CONTROL "rig./bot. dwn",IDC_ICON_ALIGN_7,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,159,73,46,44
CONTROL "border down",IDC_ICON_ALIGN_8,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,7,121,46,44
CONTROL "border H/V",IDC_ICON_ALIGN_9,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,57,121,46,44
CONTROL "round about",IDC_ICON_ALIGN_10,"Button",BS_OWNERDRAW |
BS_BOTTOM | WS_TABSTOP,110,121,46,44
CONTROL "",IDC_ICON_ALIGN_11,"Button",BS_OWNERDRAW | BS_BOTTOM |
WS_TABSTOP,159,121,46,44
CONTROL "Display &Version Number",ID_DESKTOP_VERSION,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,177,91,10
END
IDD_DESKBAR_TASKBAR DIALOG DISCARDABLE 0, 0, 210, 194
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Taskbar Properties"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "show &clock",ID_SHOW_CLOCK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,152,52,10
CONTROL "&hide inactive notification icons",
ID_HIDE_INACTIVE_ICONS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,174,111,10
PUSHBUTTON "&Notifications...",ID_CONFIG_NOTIFYAREA,153,173,50,14
END
IDD_DESKBAR_STARTMENU DIALOG DISCARDABLE 0, 0, 210, 194
STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
CAPTION "Startmenu Properties"
FONT 8, "MS Sans Serif"
BEGIN
END
IDD_NOTIFYAREA DIALOGEX 0, 0, 208, 174
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Configure Notification Icons"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "Tree1",IDC_NOTIFY_ICONS,"SysTreeView32",TVS_HASLINES |
TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,194,31
LTEXT "&Tooltip Text:",IDC_LABEL1,7,44,40,8
EDITTEXT IDC_NOTIFY_TOOLTIP,58,42,143,14,ES_AUTOHSCROLL
LTEXT "W&indow Title:",IDC_LABEL2,7,63,44,8
EDITTEXT IDC_NOTIFY_TITLE,58,60,143,14,ES_AUTOHSCROLL
LTEXT "&Module Path:",IDC_LABEL3,7,81,43,8
EDITTEXT IDC_NOTIFY_MODULE,58,78,143,14,ES_AUTOHSCROLL
GROUPBOX "&Display Mode",IDC_LABEL4,7,96,157,28
CONTROL "&show",IDC_NOTIFY_SHOW,"Button",BS_AUTORADIOBUTTON |
WS_TABSTOP,15,108,33,10
CONTROL "&hide",IDC_NOTIFY_HIDE,"Button",BS_AUTORADIOBUTTON,66,
108,29,10
CONTROL "a&utohide",IDC_NOTIFY_AUTOHIDE,"Button",
BS_AUTORADIOBUTTON,112,108,43,10
ICON "",IDC_PICTURE,173,101,21,20
LTEXT "&Last Change:",IDC_LABEL6,7,132,43,8
EDITTEXT IDC_LAST_CHANGE,59,129,105,14,ES_AUTOHSCROLL |
ES_READONLY
CONTROL "sho&w hidden",ID_SHOW_HIDDEN_ICONS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,154,56,10
DEFPUSHBUTTON "&OK",IDOK,91,153,50,14,WS_GROUP
PUSHBUTTON "&Cancel",IDCANCEL,151,153,50,14
END
IDD_MDI_SDI DIALOGEX 0, 0, 194, 157
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "cQ`gZ Kg©‡¶Î wbqš¿b"
FONT 12, "SutonnyMJ", 0, 0, 0x1
BEGIN
LTEXT "Avcbvi cQ`gZ Kg©‡¶Î wba©vib Ki“b :-",IDC_STATIC,23,7,
160,8
CONTROL "&eûgyLx Kg©‡¶Î",IDC_MDI,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,23,31,124,10
CONTROL "&GKgyLx Kg©‡¶Î",IDC_SDI,"Button",BS_AUTORADIOBUTTON,23,
61,118,10
CONTROL 170,IDC_STATIC,"Static",SS_BITMAP,145,23,15,13
CONTROL 171,IDC_STATIC,"Static",SS_BITMAP,145,57,15,13
CONTROL "GKwU Kg©‡¶†Î Dcev· ‡Lvjv",IDC_SEPARATE_SUBFOLDERS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,90,135,10
LTEXT "GB wbqgvejx mKj Kg©‡¶‡Îi Rb¨ wbw`©ó n‡e",IDC_STATIC,23,
118,174,22
DEFPUSHBUTTON "&OK",IDOK,48,140,50,10,WS_GROUP
PUSHBUTTON "&evwZj",IDCANCEL,106,140,50,10
END
IDD_ABOUT_EXPLORER DIALOG DISCARDABLE 0, 0, 199, 106
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About ReactOS Explorer"
FONT 10, "MS Sans Serif"
BEGIN
LTEXT "ReactOS Explorer",IDC_ROS_EXPLORER,91,13,104,11
LTEXT "V 0.9",IDC_VERSION_TXT,91,27,104,8
LTEXT "(c) 2003-2005 Martin Fuchs",IDC_STATIC,91,42,104,8
LTEXT "",IDC_WIN_VERSION,91,58,98,22
LTEXT "http://www.sky.franken.de/explorer/",IDC_WWW,17,84,129,
8
CONTROL "&OK",IDOK,"Button",BS_OWNERDRAW | BS_FLAT | WS_GROUP,
154,90,38,12
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE MOVEABLE PURE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE MOVEABLE PURE
BEGIN
"#include <windows.h>\r\n"
"\0"
END
3 TEXTINCLUDE MOVEABLE PURE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_TITLE "we¯—viK"
IDS_START "Kvh©Kvix ZvwjKv"
IDS_LOGOFF "Log Off..."
IDS_SHUTDOWN "eÜ Kiv..."
IDS_LAUNCH "cwiPvjbv..."
IDS_START_HELP "mvnvh¨"
IDS_SEARCH_FILES "AbymÜvb..."
IDS_DOCUMENTS "Z_¨ fvÛvi"
IDS_FAVORITES "fvj jvMv"
IDS_PROGRAMS "Kg©"
IDS_SETTINGS "wbqš¿b"
IDS_EXPLORE "we¯—vi Kiv"
IDS_EMPTY "(Empty)"
IDS_RECENT "mgmvgwqK Z_¨"
IDS_ADMIN "cÖkvmwbK"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_STARTMENU "Kvh©Kvix ZvwjKv"
IDS_MINIMIZE_ALL "mKj ev· A`„k¨ Kiv"
IDS_DESKTOP_NUM "‡W¯Uc %d"
IDS_VOLUME "AvIqvR"
IDS_ITEMS_CUR "Pjgvb ch©vq"
IDS_ITEMS_CONFIGURED "MVb ˆkwj"
IDS_ITEMS_VISIBLE "m`„k"
IDS_ITEMS_HIDDEN "A`„k¨"
IDS_NOTIFY_SHOW "‡`Lv‡bv"
IDS_NOTIFY_HIDE "jyKv‡bv"
IDS_NOTIFY_AUTOHIDE "Avcbv Avcwb jywK‡q hvIqv"
IDS_SHOW_HIDDEN_ICONS "A`„k¨ cÖwZK ‡`Lv‡bv"
IDS_HIDE_ICONS "cÖwZK jyKv‡bv "
IDS_TERMINATE "‡ivm we¯—viK eÜ Kiv"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_NETWORK "RvjK"
IDS_CONNECTIONS "Rvj‡Ki m¤ú©K"
IDS_DRIVES "wefvM"
IDS_SEARCH_COMPUTER "Kw¤úDUvi AbymÜvb..."
IDS_SETTINGS_MENU "ZvwjKv wba©vib"
IDS_CONTROL_PANEL "wbqš¿b †K`ª"
IDS_PRINTERS "wcÖUvi (Qvcv hš¿)"
IDS_BROWSE "dvBj wb‡q bvovPvov Kiv"
IDS_SEARCH_PRG "Kg© AbymÜvb...."
IDS_ALL_USERS "mKj e¨enviKvix\\"
IDS_SEARCH "AbymÜvb\n"
IDS_ABOUT_EXPLORER "&we¯—viK m¤ú©‡K..."
IDS_LAUNCH_MANY_PROGRAMS
"You have selected more than one program.\nAre you sure you want to launch all of them?"
IDS_DESKTOPBAR_SETTINGS "‡W¯Uc wbqš¿b"
IDS_DESKTOP "‡W¯Uc"
IDS_TASKBAR "Kvh©Kvix `Û"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -95,7 +95,7 @@ void ExplorerGlobals::read_persistent()
if (!_cfg.read(_cfg_path)) {
if (_cfg._last_error != XML_ERROR_NO_ELEMENTS)
MessageBox(g_Globals._hwndDesktop, String(_cfg._last_error_msg.c_str()),
MessageBox(_hwndDesktop, String(_cfg._last_error_msg.c_str()),
TEXT("ROS Explorer - reading user settings"), MB_OK);
_cfg.read(TEXT("explorer-cfg-template.xml"));
@ -540,6 +540,73 @@ const Icon& IconCache::extract(IExtractIcon* pExtract, LPCTSTR path, int icon_id
return _icons[ICID_NONE];
}
const Icon& IconCache::extract(LPCITEMIDLIST pidl, ICONCACHE_FLAGS flags)
{
// search for matching icon with unchanged flags in the cache
PidlCacheKey mapkey(pidl, flags);
PidlCacheMap::iterator found = _pidlcache.find(mapkey);
if (found != _pidlcache.end())
return _icons[found->second];
// search for matching icon with handle
PidlCacheKey mapkey_hicon(pidl, flags|ICF_HICON);
if (flags != mapkey_hicon.second) {
found = _pidlcache.find(mapkey_hicon);
if (found != _pidlcache.end())
return _icons[found->second];
}
// search for matching icon in the system image list cache
PidlCacheKey mapkey_syscache(pidl, flags|ICF_SYSCACHE);
if (flags != mapkey_syscache.second) {
found = _pidlcache.find(mapkey_syscache);
if (found != _pidlcache.end())
return _icons[found->second];
}
SHFILEINFO sfi;
int shgfi_flags = SHGFI_PIDL;
if (!(flags & (ICF_LARGE|ICF_MIDDLE)))
shgfi_flags |= SHGFI_SMALLICON;
if (flags & ICF_OPEN)
shgfi_flags |= SHGFI_OPENICON;
if (flags & ICF_SYSCACHE) {
assert(!(flags&ICF_OVERLAYS));
HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|shgfi_flags);
if (himlSys) {
const Icon& icon = add(sfi.iIcon/*, IT_SYSCACHE*/);
///@todo limit cache size
_pidlcache[mapkey_syscache] = icon;
return icon;
}
} else {
if (flags & ICF_OVERLAYS)
shgfi_flags |= SHGFI_ADDOVERLAYS;
if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_ICON|shgfi_flags)) {
const Icon& icon = add(sfi.hIcon, IT_CACHED);
///@todo limit cache size
_pidlcache[mapkey_hicon] = icon;
return icon;
}
}
return _icons[ICID_NONE];
}
const Icon& IconCache::add(HICON hIcon, ICON_TYPE type)
{
int id = ++s_next_id;

View file

@ -1,74 +1,77 @@
<module name="explorer" type="win32gui" installname="explorer.exe" allowwarnings ="true">
<linkerflag>-luuid</linkerflag>
<linkerflag>-lstdc++</linkerflag>
<linkerflag>-fexceptions</linkerflag>
<include base="explorer">.</include>
<define name="__USE_W32API" />
<define name="UNICODE" />
<define name="WIN32" />
<define name="_ROS_" />
<define name="_WIN32_IE">0x0600</define>
<define name="_WIN32_WINNT">0x0501</define>
<define name="WINVER">0x0500</define>
<define name="__WINDRES__" />
<library>kernel32</library>
<library>gdi32</library>
<library>user32</library>
<library>ws2_32</library>
<library>msimg32</library>
<library>comctl32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>shell32</library>
<library>expat</library>
<library>notifyhook</library>
<pch>precomp.h</pch>
<directory name="desktop">
<file>desktop.cpp</file>
</directory>
<directory name="dialogs">
<file>searchprogram.cpp</file>
<file>settings.cpp</file>
</directory>
<directory name="shell">
<file>entries.cpp</file>
<file>fatfs.cpp</file>
<file>filechild.cpp</file>
<file>shellfs.cpp</file>
<file>mainframe.cpp</file>
<file>ntobjfs.cpp</file>
<file>pane.cpp</file>
<file>regfs.cpp</file>
<file>shellbrowser.cpp</file>
<file>unixfs.cpp</file>
<file>webchild.cpp</file>
<file>winfs.cpp</file>
</directory>
<directory name="services">
<file>shellservices.cpp</file>
<file>startup.c</file>
</directory>
<directory name="taskbar">
<file>desktopbar.cpp</file>
<file>favorites.cpp</file>
<file>taskbar.cpp</file>
<file>startmenu.cpp</file>
<file>traynotify.cpp</file>
<file>quicklaunch.cpp</file>
</directory>
<directory name="utility">
<file>shellclasses.cpp</file>
<file>utility.cpp</file>
<file>window.cpp</file>
<file>dragdropimpl.cpp</file>
<file>shellbrowserimpl.cpp</file>
<file>xmlstorage.cpp</file>
</directory>
<file>explorer.cpp</file>
<file>i386-stub-win32.c</file>
<file>explorer.rc</file>
</module>
<installfile base=".">explorer-cfg-template.xml</installfile>
<directory name="notifyhook">
<xi:include href="notifyhook/notifyhook.rbuild" />
</directory>
<?xml version="1.0"?>
<rbuild xmlns:xi="http://www.w3.org/2001/XInclude">
<module name="explorer" type="win32gui" installname="explorer.exe" allowwarnings="true">
<linkerflag>-luuid</linkerflag>
<linkerflag>-lstdc++</linkerflag>
<linkerflag>-fexceptions</linkerflag>
<include base="explorer">.</include>
<define name="__USE_W32API" />
<define name="UNICODE" />
<define name="WIN32" />
<define name="_ROS_" />
<define name="_WIN32_IE">0x0600</define>
<define name="_WIN32_WINNT">0x0501</define>
<define name="WINVER">0x0500</define>
<define name="__WINDRES__" />
<library>kernel32</library>
<library>gdi32</library>
<library>user32</library>
<library>ws2_32</library>
<library>msimg32</library>
<library>comctl32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>shell32</library>
<library>expat</library>
<library>notifyhook</library>
<pch>precomp.h</pch>
<directory name="desktop">
<file>desktop.cpp</file>
</directory>
<directory name="dialogs">
<file>searchprogram.cpp</file>
<file>settings.cpp</file>
</directory>
<directory name="shell">
<file>entries.cpp</file>
<file>fatfs.cpp</file>
<file>filechild.cpp</file>
<file>shellfs.cpp</file>
<file>mainframe.cpp</file>
<file>ntobjfs.cpp</file>
<file>pane.cpp</file>
<file>regfs.cpp</file>
<file>shellbrowser.cpp</file>
<file>unixfs.cpp</file>
<file>webchild.cpp</file>
<file>winfs.cpp</file>
</directory>
<directory name="services">
<file>shellservices.cpp</file>
<file>startup.c</file>
</directory>
<directory name="taskbar">
<file>desktopbar.cpp</file>
<file>favorites.cpp</file>
<file>taskbar.cpp</file>
<file>startmenu.cpp</file>
<file>traynotify.cpp</file>
<file>quicklaunch.cpp</file>
</directory>
<directory name="utility">
<file>shellclasses.cpp</file>
<file>utility.cpp</file>
<file>window.cpp</file>
<file>dragdropimpl.cpp</file>
<file>shellbrowserimpl.cpp</file>
<file>xmlstorage.cpp</file>
</directory>
<file>explorer.cpp</file>
<file>i386-stub-win32.c</file>
<file>explorer.rc</file>
</module>
<installfile base=".">explorer-cfg-template.xml</installfile>
<directory name="notifyhook">
<xi:include href="notifyhook/notifyhook.rbuild" />
</directory>
</rbuild>

View file

@ -130,6 +130,7 @@ struct IconCache {
const Icon& extract(LPCTSTR path, ICONCACHE_FLAGS flags=ICF_NORMAL);
const Icon& extract(LPCTSTR path, int icon_idx, ICONCACHE_FLAGS flags=ICF_HICON);
const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int icon_idx, ICONCACHE_FLAGS flags=ICF_HICON);
const Icon& extract(LPCITEMIDLIST pidl, ICONCACHE_FLAGS flags=ICF_NORMAL);
const Icon& add(HICON hIcon, ICON_TYPE type=IT_DYNAMIC);
const Icon& add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/);
@ -154,6 +155,10 @@ protected:
typedef map<IdxCacheKey, ICON_ID> IdxCacheMap;
IdxCacheMap _idxCache;
typedef pair<ShellPath,int/*ICONCACHE_FLAGS*/> PidlCacheKey;
typedef map<PidlCacheKey, ICON_ID> PidlCacheMap;
PidlCacheMap _pidlcache;
HIMAGELIST _himlSys_small;
};
@ -165,7 +170,7 @@ protected:
#define STARTMENUROOT_ICON_SIZE ICON_SIZE_MIDDLE // ICON_SIZE_LARGE
#define ICON_SIZE_FROM_ICF(flags) (flags&ICF_LARGE? ICON_SIZE_LARGE: flags&ICF_MIDDLE? ICON_SIZE_MIDDLE: ICON_SIZE_SMALL)
#define ICF_FROM_ICON_SIZE(size) (size>=ICON_SIZE_LARGE? ICF_LARGE: size>=ICON_SIZE_MIDDLE? ICF_MIDDLE: ICF_NORMAL)
#define ICF_FROM_ICON_SIZE(size) (size>=ICON_SIZE_LARGE? ICF_LARGE: size>=ICON_SIZE_MIDDLE? ICF_MIDDLE: (ICONCACHE_FLAGS)0)
/// create a bitmap from an icon

View file

@ -45,7 +45,7 @@ CFG=make_explorer - Win32 bjam
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.PCH UNICODE=0"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile-precomp UNICODE=0"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name ""
@ -66,7 +66,7 @@ CFG=make_explorer - Win32 bjam
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.PCH UNICODE=0 DEBUG=1"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile-precomp UNICODE=0 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=0 DEBUG=1"
@ -108,7 +108,7 @@ CFG=make_explorer - Win32 bjam
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "URelease"
# PROP Intermediate_Dir "URelease"
# PROP Cmd_Line "msdevfilt -gcc make -f Makefile.PCH UNICODE=1"
# PROP Cmd_Line "msdevfilt -gcc make -f Makefile-precomp UNICODE=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "explorer.exe"
# PROP Bsc_Name ""
@ -183,6 +183,10 @@ CFG=make_explorer - Win32 bjam
# Begin Source File
SOURCE=.\explorer.rbuild
# End Source File
# Begin Source File
SOURCE=.\Jamfile
# End Source File
# Begin Source File
@ -191,15 +195,15 @@ SOURCE=.\Makefile
# End Source File
# Begin Source File
SOURCE=.\Makefile.MinGW
SOURCE=".\Makefile-MinGW"
# End Source File
# Begin Source File
SOURCE=.\Makefile.PCH
SOURCE=".\Makefile-precomp"
# End Source File
# Begin Source File
SOURCE=.\Makefile.Wine
SOURCE=".\Makefile-Wine"
# End Source File
# End Target
# End Project

View file

@ -25,8 +25,8 @@
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="msdevfilt -gcc make -f Makefile.PCH UNICODE=1"
ReBuildCommandLine="msdevfilt -gcc make -f Makefile.PCH UNICODE=1 clean all"
BuildCommandLine="msdevfilt -gcc make -f Makefile-precomp UNICODE=1"
ReBuildCommandLine="msdevfilt -gcc make -f Makefile-precomp UNICODE=1 clean all"
CleanCommandLine=""
Output="explorer.exe"
PreprocessorDefinitions=""
@ -71,8 +71,8 @@
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile.PCH UNICODE=0"
ReBuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile.PCH UNICODE=0 clean all"
BuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile-precomp UNICODE=0"
ReBuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile-precomp UNICODE=0 clean all"
CleanCommandLine=""
Output="explorer.exe"
PreprocessorDefinitions=""
@ -140,8 +140,8 @@
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile.PCH UNICODE=0 DEBUG=1"
ReBuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile.PCH UNICODE=0 DEBUG=1 clean all"
BuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile-precomp UNICODE=0 DEBUG=1"
ReBuildCommandLine="msdevfilt -gcc -pipe &quot;perl d:\tools\gSTLFilt.pl&quot; make -f Makefile-precomp UNICODE=0 DEBUG=1 clean all"
CleanCommandLine=""
Output="explorer.exe"
PreprocessorDefinitions=""
@ -173,7 +173,7 @@
>
</File>
<File
RelativePath="Makefile.PCH"
RelativePath="Makefile-precomp"
>
</File>
<File

View file

@ -43,7 +43,7 @@ CFG=make_rosshell - Win32 Release
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Make-rosshell.MinGW UNICODE=0"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Make-rosshell-MinGW UNICODE=0"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "rosshell.exe"
# PROP Bsc_Name ""
@ -64,7 +64,7 @@ CFG=make_rosshell - Win32 Release
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Make-rosshell.MinGW UNICODE=0 DEBUG=1"
# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Make-rosshell-MinGW UNICODE=0 DEBUG=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "rosshell.exe"
# PROP Bsc_Name "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=0 DEBUG=1"
@ -106,7 +106,7 @@ CFG=make_rosshell - Win32 Release
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "URelease"
# PROP Intermediate_Dir "URelease"
# PROP Cmd_Line "msdevfilt -gcc make -f Make-rosshell.MinGW UNICODE=1"
# PROP Cmd_Line "msdevfilt -gcc make -f Make-rosshell-MinGW UNICODE=1"
# PROP Rebuild_Opt "clean all"
# PROP Target_File "rosshell.exe"
# PROP Bsc_Name ""
@ -137,19 +137,15 @@ SOURCE=.\Jamfile
# End Source File
# Begin Source File
SOURCE=".\Make-rosshell.MinGW"
SOURCE=".\Make-rosshell-MinGW"
# End Source File
# Begin Source File
SOURCE=".\Make-rosshell.mak"
# End Source File
# Begin Source File
SOURCE=.\Makefile
# End Source File
# Begin Source File
SOURCE=.\Makefile.MinGW
# End Source File
# Begin Source File
SOURCE=.\Makefile.Wine
# End Source File
# End Target
# End Project

View file

@ -128,5 +128,13 @@ SOURCE=.\notifyhook.c
SOURCE=.\notifyhook.h
# End Source File
# Begin Source File
SOURCE=.\notifyhook.rbuild
# End Source File
# Begin Source File
SOURCE=..\utility\utility.h
# End Source File
# End Target
# End Project

View file

@ -1,10 +1,13 @@
<module name="notifyhook" type="win32dll" baseaddress="${BASEADDRESS_NOTIFYHOOK}" installbase="system32" installname="notifyhook.dll">
<importlibrary definition="notifyhook.def" />
<include base="notifyhook">.</include>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x0600</define>
<define name="_NOTIFYHOOK_IMPL" />
<library>kernel32</library>
<file>notifyhook.c</file>
<file>notifyhook.rc</file>
</module>
<?xml version="1.0"?>
<rbuild xmlns:xi="http://www.w3.org/2001/XInclude">
<module name="notifyhook" type="win32dll" baseaddress="${BASEADDRESS_NOTIFYHOOK}" installbase="system32" installname="notifyhook.dll">
<importlibrary definition="notifyhook.def" />
<include base="notifyhook">.</include>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x0600</define>
<define name="_NOTIFYHOOK_IMPL" />
<library>kernel32</library>
<file>notifyhook.c</file>
<file>notifyhook.rc</file>
</module>
</rbuild>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

View file

@ -413,32 +413,10 @@ int Entry::extract_icon(ICONCACHE_FLAGS flags)
}
if (icon_id == ICID_NONE) {
SHFILEINFO sfi;
const ShellPath& pidl_abs = create_absolute_pidl();
LPCITEMIDLIST pidl = pidl_abs;
int shgfi_flags = SHGFI_PIDL;
if (!(flags & (ICF_LARGE|ICF_MIDDLE)))
shgfi_flags |= SHGFI_SMALLICON;
if (flags & ICF_OPEN)
shgfi_flags |= SHGFI_OPENICON;
if (flags & ICF_SYSCACHE) {
assert(!(flags&ICF_OVERLAYS));
HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|shgfi_flags);
if (himlSys)
icon_id = g_Globals._icon_cache.add(sfi.iIcon);
} else {
if (flags & ICF_OVERLAYS)
shgfi_flags |= SHGFI_ADDOVERLAYS;
if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_ICON|shgfi_flags))
icon_id = g_Globals._icon_cache.add(sfi.hIcon);
}
icon_id = g_Globals._icon_cache.extract(pidl, flags);
}
}

View file

@ -304,8 +304,9 @@ bool MainFrameBase::ProcessMessage(UINT nmsg, WPARAM wparam, LPARAM lparam, LRES
MoveWindow(_hwndrebar, 0, 0, LOWORD(lparam), height, TRUE);
#else
resize_frame(LOWORD(lparam), HIWORD(lparam));
SendMessage(_hwndrebar, WM_SIZE, 0, 0);
#endif
} break; // do not pass message to DefFrameProc
break;} // do not pass message to DefFrameProc
case WM_GETMINMAXINFO: {
LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;

View file

@ -70,12 +70,16 @@ LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
String COMException::toString() const
{
TCHAR msg[4*BUFFER_LEN];
#ifdef __STDC_WANT_SECURE_LIB__
int l = 4*BUFFER_LEN;
#endif
LPTSTR p = msg;
int n = _stprintf_s2(p, l, TEXT("%s\nContext: %s"), super::ErrorMessage(), (LPCTSTR)_context.toString());
p += n;
#ifdef __STDC_WANT_SECURE_LIB__
l -= n;
#endif
if (_file)
p += _stprintf_s2(p, l, TEXT("\nLocation: %hs:%d"), _file, _line);

View file

@ -791,6 +791,18 @@ struct ShellPath : public SShellPtr<ITEMIDLIST>
_p = (ITEMIDLIST*)p;
}
friend bool operator<(const ShellPath& a, const ShellPath& b)
{
int la = ILGetSize(a._p);
int lb = ILGetSize(b._p);
int r = memcmp(a._p, b._p, min(la, lb));
if (r)
return r < 0;
else
return la < lb;
}
void assign(LPCITEMIDLIST pidl, size_t size)
{
//CONTEXT("ShellPath::assign(LPCITEMIDLIST, size_t)");

View file

@ -392,7 +392,7 @@ LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
ClientRect rt(_hwnd);
rt.left = _split_pos-SPLIT_WIDTH/2;
rt.right = _split_pos+SPLIT_WIDTH/2+1;
HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(LTGRAY_BRUSH));
HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
SetRect(&rc, rt.left, rt.top-1, rt.right, rt.bottom+1);
DrawEdge(canvas, &rc, EDGE_RAISED, BF_RECT);

View file

@ -4,7 +4,7 @@
//
// xmlstorage.cpp
//
// Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs@gmx.net>
// Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs@gmx.net>
//
@ -48,7 +48,8 @@
#ifdef __GNUC__
const LPCXSSTR XMLStorage::XS_TRUE = XS_TRUE_STR;
const LPCXSSTR XMLStorage::XS_FALSE = XS_FALSE_STR;
const LPCXSSTR XMLStorage::XS_NUMBERFMT = XS_NUMBERFMT_STR;
const LPCXSSTR XMLStorage::XS_INTFMT = XS_INTFMT_STR;
const LPCXSSTR XMLStorage::XS_FLOATFMT = XS_FLOATFMT_STR;
#endif
@ -143,7 +144,7 @@ const XMLNode* XMLNode::find_relative(const char* path) const
if (slash == path)
return NULL;
int l = slash? slash-path: strlen(path);
size_t l = slash? slash-path: strlen(path);
std::string comp(path, l);
path += l;
@ -265,201 +266,6 @@ XMLNode* XMLNode::create_relative(const char* path)
}
/// read XML stream into XML tree below _pos
XML_Status XMLReaderBase::read()
{
XML_Status status = XML_STATUS_OK;
while(status == XML_STATUS_OK) {
char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
int l = read_buffer(buffer, BUFFER_LEN);
if (l < 0)
break;
status = XML_ParseBuffer(_parser, l, false);
}
if (status != XML_STATUS_ERROR)
status = XML_ParseBuffer(_parser, 0, true);
if (_pos->_children.empty())
_pos->_trailing.append(_content);
else
_pos->_children.back()->_trailing.append(_content);
_content.erase();
return status;
}
/// store XML version and encoding into XML reader
void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
if (version)
pReader->_xml_version = version;
if (encoding)
pReader->_encoding = encoding;
}
/// notifications about XML start tag
void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLPos& pos = pReader->_pos;
// search for end of first line
const char* s = pReader->_content.c_str();
const char* p = s;
const char* e = p + pReader->_content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (pos->_children.empty()) { // no children in last node?
if (pReader->_last_tag == TAG_START)
pos->_content.append(s, p-s);
else if (pReader->_last_tag == TAG_END)
pos->_trailing.append(s, p-s);
// else TAG_NONE -> don't store white space in root node
} else
pos->_children.back()->_trailing.append(s, p-s);
std::string leading;
if (p != e)
leading.assign(p, e-p);
XMLNode* node = new XMLNode(String_from_XML_Char(name), leading);
pos.add_down(node);
while(*atts) {
const XML_Char* attr_name = *atts++;
const XML_Char* attr_value = *atts++;
(*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
}
pReader->_last_tag = TAG_START;
pReader->_content.erase();
}
/// notifications about XML end tag
void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLPos& pos = pReader->_pos;
// search for end of first line
const char* s = pReader->_content.c_str();
const char* p = s;
const char* e = p + pReader->_content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (pos->_children.empty()) // no children in current node?
pos->_content.append(s, p-s);
else
if (pReader->_last_tag == TAG_START)
pos->_content.append(s, p-s);
else
pos->_children.back()->_trailing.append(s, p-s);
if (p != e)
pos->_end_leading.assign(p, e-p);
pos.back();
pReader->_last_tag = TAG_END;
pReader->_content.erase();
}
/// store content, white space and comments
void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->_content.append(s, len);
}
/// return error strings for Expat errors
std::string XMLReaderBase::get_error_string() const
{
XML_Error error = XML_GetErrorCode(_parser);
switch(error) {
case XML_ERROR_NONE: return "XML_ERROR_NONE";
case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY";
case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX";
case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS";
case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN";
case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN";
case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR";
case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH";
case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE";
case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF";
case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY";
case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF";
case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY";
case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF";
case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF";
case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI";
case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING";
case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING";
case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION";
case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE";
case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE";
case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE";
case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX";
// EXPAT version >= 1.95.8
#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7)
case XML_ERROR_UNDECLARING_PREFIX: return "XML_ERROR_UNDECLARING_PREFIX";
case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE";
case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL";
case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL";
case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID";
case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED";
case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED";
case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED";
case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED";
case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE";
#endif
#if XML_MAJOR_VERSION>=2
/* Added in 2.0. */
case XML_ERROR_RESERVED_PREFIX_XML: return "XML_ERROR_RESERVED_PREFIX_XML";
case XML_ERROR_RESERVED_PREFIX_XMLNS: return "XML_ERROR_RESERVED_PREFIX_XMLNS";
case XML_ERROR_RESERVED_NAMESPACE_URI: return "XML_ERROR_RESERVED_NAMESPACE_URI";
#endif
}
std::ostringstream out;
out << "XML parser error #" << error;
return out.str();
}
/// encode XML string literals
std::string EncodeXMLString(const XS_String& str)
{
@ -635,4 +441,284 @@ void XMLNode::smart_write_worker(std::ostream& out, int indent) const
}
/// read XML stream into XML tree below _pos
XML_Status XMLReaderBase::read()
{
XML_Status status = XML_STATUS_OK;
while(status == XML_STATUS_OK) {
char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
size_t l = read_buffer(buffer, BUFFER_LEN);
if ((int)l < 0)
break;
status = XML_ParseBuffer(_parser, l, false);
}
if (status != XML_STATUS_ERROR)
status = XML_ParseBuffer(_parser, 0, true);
finish_read();
return status;
}
/// return current parser position as string
std::string XMLReaderBase::get_position() const
{
int line = XML_GetCurrentLineNumber(_parser);
int column = XML_GetCurrentColumnNumber(_parser);
std::ostringstream out;
out << "(" << line << ") : [column " << column << "]";
return out.str();
}
#ifdef XMLNODE_LOCATION
XMLLocation XMLReaderBase::get_location() const
{
int line = XML_GetCurrentLineNumber(_parser);
int column = XML_GetCurrentColumnNumber(_parser);
return XMLLocation(_display_path, line, column);
}
std::string XMLLocation::str() const
{
std::ostringstream out;
if (_pdisplay_path)
out << _pdisplay_path;
out << "(" << _line << ") : [column " << _column << "]";
return out.str();
}
#endif
/// return current error code from Expat
XML_Error XMLReaderBase::get_error_code() const
{
return XML_GetErrorCode(_parser);
}
/// store XML version and encoding into XML reader
void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->XmlDeclHandler(version, encoding, standalone);
}
/// notifications about XML start tag
void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
XMLNode::AttributeMap attributes;
while(*atts) {
const XML_Char* attr_name = *atts++;
const XML_Char* attr_value = *atts++;
attributes[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
}
pReader->StartElementHandler(String_from_XML_Char(name), attributes);
}
/// notifications about XML end tag
void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->EndElementHandler();
}
/// store content, white space and comments
void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
{
XMLReaderBase* pReader = (XMLReaderBase*) userData;
pReader->DefaultHandler(s, len);
}
/// return error strings for Expat errors
std::string XMLReaderBase::get_error_string() const
{
XML_Error error = XML_GetErrorCode(_parser);
switch(error) {
case XML_ERROR_NONE: return "XML_ERROR_NONE";
case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY";
case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX";
case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS";
case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN";
case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN";
case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR";
case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH";
case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE";
case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF";
case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY";
case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF";
case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY";
case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF";
case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF";
case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI";
case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING";
case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING";
case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION";
case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE";
case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE";
case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE";
case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX";
// EXPAT version >= 1.95.8
#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7)
case XML_ERROR_UNDECLARING_PREFIX: return "XML_ERROR_UNDECLARING_PREFIX";
case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE";
case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL";
case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL";
case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID";
case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED";
case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED";
case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED";
case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED";
case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE";
#endif
#if XML_MAJOR_VERSION>=2
/* Added in 2.0. */
case XML_ERROR_RESERVED_PREFIX_XML: return "XML_ERROR_RESERVED_PREFIX_XML";
case XML_ERROR_RESERVED_PREFIX_XMLNS: return "XML_ERROR_RESERVED_PREFIX_XMLNS";
case XML_ERROR_RESERVED_NAMESPACE_URI: return "XML_ERROR_RESERVED_NAMESPACE_URI";
#endif
}
std::ostringstream out;
out << "XML parser error #" << error;
return out.str();
}
void XMLReaderBase::finish_read()
{
if (_pos->_children.empty())
_pos->_trailing.append(_content);
else
_pos->_children.back()->_trailing.append(_content);
_content.erase();
}
/// store XML version and encoding into XML reader
void XMLReaderBase::XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int standalone)
{
if (version)
_xml_version = version;
if (encoding)
_encoding = encoding;
}
/// notifications about XML start tag
void XMLReaderBase::StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes)
{
// search for end of first line
const char* s = _content.c_str();
const char* p = s;
const char* e = p + _content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (_pos->_children.empty()) { // no children in last node?
if (_last_tag == TAG_START)
_pos->_content.append(s, p-s);
else if (_last_tag == TAG_END)
_pos->_trailing.append(s, p-s);
// else TAG_NONE -> don't store white space in root node
} else
_pos->_children.back()->_trailing.append(s, p-s);
std::string leading;
if (p != e)
leading.assign(p, e-p);
XMLNode* node = new XMLNode(name, leading);
_pos.add_down(node);
#ifdef XMLNODE_LOCATION
node->_location = get_location();
#endif
node->_attributes = attributes;
_last_tag = TAG_START;
_content.erase();
}
/// notifications about XML end tag
void XMLReaderBase::EndElementHandler()
{
// search for end of first line
const char* s = _content.c_str();
const char* p = s;
const char* e = p + _content.length();
for(; p<e; ++p)
if (*p == '\n') {
++p;
break;
}
if (p != s)
if (_pos->_children.empty()) // no children in current node?
_pos->_content.append(s, p-s);
else
if (_last_tag == TAG_START)
_pos->_content.append(s, p-s);
else
_pos->_children.back()->_trailing.append(s, p-s);
if (p != e)
_pos->_end_leading.assign(p, e-p);
_pos.back();
_last_tag = TAG_END;
_content.erase();
}
/// store content, white space and comments
void XMLReaderBase::DefaultHandler(const XML_Char* s, int len)
{
_content.append(s, len);
}
XS_String XMLWriter::s_empty_attr;
} // namespace XMLStorage

View file

@ -4,7 +4,7 @@
//
// xmlstorage.h
//
// Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs@gmx.net>
// Copyright (c) 2004, 2005, 2006 Martin Fuchs <martin-fuchs@gmx.net>
//
@ -38,19 +38,91 @@
#ifndef _XMLSTORAGE_H
#if _MSC_VER>=1400
#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
#endif
#endif
#ifndef _NO_EXPAT
//#include "expat.h"
#include <expat/expat.h>
#ifdef _MSC_VER
#pragma comment(lib, "libexpat.lib")
#pragma warning(disable: 4786)
#else
typedef char XML_Char;
enum XML_Status {
XML_STATUS_ERROR = 0,
XML_STATUS_OK = 1
};
enum XML_Error {
XML_ERROR_NONE,
XML_ERROR_FAILURE
};
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#ifndef _NO_COMMENT
#ifndef _NO_EXPAT
#ifdef XML_STATIC
#ifndef _DEBUG
#pragma comment(lib, "libexpatMT")
#endif
#else
#pragma comment(lib, "libexpat")
#endif
#endif
#ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded in the project
#if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8d")
#else
#pragma comment(lib, "xmlstorage-vc6d")
#endif
#else
#ifdef _DLL
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8")
#else
#pragma comment(lib, "xmlstorage-vc6")
#endif
#elif defined(_MT)
#if _MSC_VER==1400
#pragma comment(lib, "xmlstorage-vc8t")
#else
#pragma comment(lib, "xmlstorage-vc6t")
#endif
#else
// -ML is no more supported by VS2005.
#pragma comment(lib, "xmlstorage-vc6l")
#endif
#endif
#endif // _STRING_DEFINED
#endif // _NO_COMMENT
#endif // _MSC_VER
#include <windows.h> // for LPCTSTR
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
#include <tchar.h>
#include <malloc.h>
@ -81,6 +153,7 @@ namespace XMLStorage {
#define XS_icmp stricmp
#define XS_nicmp strnicmp
#define XS_toi atoi
#define XS_tod strtod
#define XS_len strlen
#define XS_snprintf snprintf
#define XS_vsnprintf vsnprintf
@ -92,14 +165,19 @@ namespace XMLStorage {
#define XS_icmp _tcsicmp
#define XS_nicmp _tcsnicmp
#define XS_toi _ttoi
#define XS_tod _tcstod
#define XS_len _tcslen
#define XS_snprintf _sntprintf
#define XS_vsnprintf _vsntprintf
#endif
#ifndef COUNTOF
#if _MSC_VER>=1400
#define COUNTOF _countof
#else
#define COUNTOF(b) (sizeof(b)/sizeof(b[0]))
#endif
#endif
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
@ -269,7 +347,6 @@ typedef __gnu_cxx::stdio_filebuf<char> STDIO_FILEBUF;
typedef std::filebuf STDIO_FILEBUF;
#endif
struct FileHolder
{
FileHolder(LPCTSTR path, LPCTSTR mode)
@ -382,6 +459,34 @@ inline bool operator==(const XS_String& s1, const char* s2)
#endif
#ifdef XMLNODE_LOCATION
/// location of XML Node including XML file name
struct XMLLocation
{
XMLLocation()
: _pdisplay_path(NULL),
_line(0),
_column(0)
{
}
XMLLocation(const char* display_path, int line, int column)
: _pdisplay_path(display_path),
_line(line),
_column(column)
{
}
std::string str() const;
protected:
const char* _pdisplay_path; // character pointer for fast reference
int _line;
int _column;
};
#endif
/// in memory representation of an XML node
struct XMLNode : public XS_String
{
@ -454,7 +559,8 @@ struct XMLNode : public XS_String
}
XMLNode(const XMLNode& other)
: _attributes(other._attributes),
: XS_String(other),
_attributes(other._attributes),
_leading(other._leading),
_content(other._content),
_end_leading(other._end_leading),
@ -462,6 +568,10 @@ struct XMLNode : public XS_String
{
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
_children.push_back(new XMLNode(**it));
#ifdef XMLNODE_LOCATION
_location = other._location;
#endif
}
~XMLNode()
@ -588,6 +698,16 @@ struct XMLNode : public XS_String
return _children;
}
const AttributeMap& get_attributes() const
{
return _attributes;
}
AttributeMap& get_attributes()
{
return _attributes;
}
XS_String get_content() const
{
#ifdef XS_STRING_UTF8
@ -605,6 +725,10 @@ struct XMLNode : public XS_String
_content.assign(EncodeXMLString(s.c_str()));
}
#ifdef XMLNODE_LOCATION
const XMLLocation& get_location() const {return _location;}
#endif
enum WRITE_MODE {
FORMAT_SMART = 0, /// preserve original white space and comments if present; pretty print otherwise
FORMAT_ORIGINAL = 1, /// write XML stream preserving original white space and comments
@ -639,6 +763,10 @@ protected:
std::string _end_leading;
std::string _trailing;
#ifdef XMLNODE_LOCATION
XMLLocation _location;
#endif
XMLNode* get_first_child() const
{
if (!_children.empty())
@ -706,9 +834,9 @@ protected:
/// relative XPath create function
XMLNode* create_relative(const char* path);
void write_worker(std::ostream& out, int indent) const;
void pretty_write_worker(std::ostream& out, int indent) const;
void smart_write_worker(std::ostream& out, int indent) const;
void write_worker(std::ostream& out, int indent) const;
void pretty_write_worker(std::ostream& out, int indent) const;
void smart_write_worker(std::ostream& out, int indent) const;
};
@ -1242,17 +1370,20 @@ protected:
#define XS_TRUE_STR XS_TEXT("true")
#define XS_FALSE_STR XS_TEXT("false")
#define XS_NUMBERFMT_STR XS_TEXT("%d")
#define XS_INTFMT_STR XS_TEXT("%d")
#define XS_FLOATFMT_STR XS_TEXT("%f")
// work around GCC's wide string constant bug
#ifdef __GNUC__
extern const LPCXSSTR XS_TRUE;
extern const LPCXSSTR XS_FALSE;
extern const LPCXSSTR XS_NUMBERFMT;
extern const LPCXSSTR XS_INTFMT;
extern const LPCXSSTR XS_FLOATFMT;
#else
#define XS_TRUE XS_TRUE_STR
#define XS_FALSE XS_FALSE_STR
#define XS_NUMBERFMT XS_NUMBERFMT_STR
#define XS_INTFMT XS_INTFMT_STR
#define XS_FLOATFMT XS_FLOATFMT_STR
#endif
@ -1380,7 +1511,7 @@ struct XMLInt
operator XS_String() const
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_NUMBERFMT, _value);
XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value);
return buffer;
}
@ -1416,7 +1547,90 @@ struct XMLIntRef
void assign(int value)
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_NUMBERFMT, value);
XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value);
_ref.assign(buffer);
}
protected:
XS_String& _ref;
};
/// type converter for numeric data
struct XMLDouble
{
XMLDouble(double value)
: _value(value)
{
}
XMLDouble(LPCXSSTR value, double def=0.)
{
LPTSTR end;
if (value && *value)
_value = XS_tod(value, &end);
else
_value = def;
}
XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.)
{
LPTSTR end;
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = XS_tod(value.c_str(), &end);
else
_value = def;
}
operator double() const
{
return _value;
}
operator XS_String() const
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value);
return buffer;
}
protected:
double _value;
private:
void operator=(const XMLDouble&); // disallow assignment operations
};
/// type converter for numeric data with write access
struct XMLDoubleRef
{
XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMLDoubleRef& operator=(double value)
{
assign(value);
return *this;
}
operator double() const
{
LPTSTR end;
return XS_tod(_ref.c_str(), &end);
}
void assign(double value)
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value);
_ref.assign(buffer);
}
@ -1552,24 +1766,20 @@ struct XMLReaderBase
XML_Status read();
std::string get_position() const;
std::string get_instructions() const {return _instructions;}
XML_Error get_error_code() const;
std::string get_error_string() const;
#ifdef XMLNODE_LOCATION
const char* _display_path; // character pointer for fast reference in XMLLocation
XMLLocation get_location() const;
#endif
virtual int read_buffer(char* buffer, int len) = 0;
std::string get_position() const
{
int line = XML_GetCurrentLineNumber(_parser);
int column = XML_GetCurrentColumnNumber(_parser);
std::ostringstream out;
out << "(" << line << ") : [column " << column << "]";
return out.str();
}
std::string get_instructions() const {return _instructions;}
XML_Error get_error_code() {return XML_GetErrorCode(_parser);}
std::string get_error_string() const;
protected:
XMLPos _pos;
XML_Parser _parser;
@ -1580,6 +1790,13 @@ protected:
std::string _content;
enum {TAG_NONE, TAG_START, TAG_END} _last_tag;
void finish_read();
virtual void XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int standalone);
virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes);
virtual void EndElementHandler();
virtual void DefaultHandler(const XML_Char* s, int len);
static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone);
static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name);
@ -1612,7 +1829,7 @@ protected:
};
/// management of XML file headers
/// Management of XML file headers
struct XMLHeader
{
XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="")
@ -1659,13 +1876,11 @@ struct XMLDoc : public XMLNode
read(path);
}
std::istream& read(std::istream& in)
bool read(std::istream& in)
{
XMLReader reader(this, in);
read(reader);
return in;
return read(reader);
}
bool read(LPCTSTR path)
@ -1700,6 +1915,11 @@ struct XMLDoc : public XMLNode
bool read(XMLReaderBase& reader, const std::string& display_path)
{
#ifdef XMLNODE_LOCATION
// make a string copy to handle temporary string objects
_display_path = display_path;
reader._display_path = _display_path.c_str();
#endif
XML_Status status = reader.read();
_header._additional = reader.get_instructions();
@ -1750,6 +1970,10 @@ struct XMLDoc : public XMLNode
XMLHeader _header;
XML_Error _last_error;
std::string _last_error_msg;
#ifdef XMLNODE_LOCATION
std::string _display_path;
#endif
};
@ -1848,7 +2072,7 @@ struct XMLWriter
void set_content(const XS_String& s)
{
if (!_stack.empty())
_stack.top()._content = s;
_stack.top()._content = EncodeXMLString(s.c_str());
}
// public for access in StackEntry
@ -1890,7 +2114,7 @@ protected:
_out << std::endl;
if (_pretty == PRETTY_INDENT)
for(int i=_stack.size(); --i>0; )
for(size_t i=_stack.size(); --i>0; )
_out << XML_INDENT_SPACE;
_out << '<' << EncodeXMLString(entry._node_name);
@ -1921,7 +2145,7 @@ protected:
_out << std::endl;
if (_pretty==PRETTY_INDENT && entry._content.empty())
for(int i=_stack.size(); --i>0; )
for(size_t i=_stack.size(); --i>0; )
_out << XML_INDENT_SPACE;
_out << "</" << EncodeXMLString(entry._node_name) << ">";