import of enigma2
authorFelix Domke <tmbinc@elitedvb.net>
Fri, 17 Oct 2003 15:36:42 +0000 (15:36 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Fri, 17 Oct 2003 15:36:42 +0000 (15:36 +0000)
360 files changed:
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
DEADJOE [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
autom4te.cache/output.0 [new file with mode: 0644]
autom4te.cache/requests [new file with mode: 0644]
autom4te.cache/traces.0 [new file with mode: 0644]
config.h.in [new file with mode: 0644]
configure [new file with mode: 0755]
configure.ac [new file with mode: 0644]
debug [new file with mode: 0755]
debug.gdb [new file with mode: 0644]
include/connection.h [new file with mode: 0644]
include/libsig_comp.h [new file with mode: 0644]
lib/DEADJOE [new file with mode: 0644]
lib/Makefile.am [new file with mode: 0644]
lib/Makefile.in [new file with mode: 0644]
lib/base/Makefile.am [new file with mode: 0644]
lib/base/Makefile.in [new file with mode: 0644]
lib/base/a [new file with mode: 0644]
lib/base/buffer.cpp [new file with mode: 0644]
lib/base/buffer.h [new file with mode: 0644]
lib/base/console.cpp [new file with mode: 0644]
lib/base/console.h [new file with mode: 0644]
lib/base/ebase.cpp [new file with mode: 0644]
lib/base/ebase.h [new file with mode: 0644]
lib/base/econfig.cpp [new file with mode: 0644]
lib/base/econfig.h [new file with mode: 0644]
lib/base/eerror.cpp [new file with mode: 0644]
lib/base/eerror.h [new file with mode: 0644]
lib/base/elock.cpp [new file with mode: 0644]
lib/base/elock.h [new file with mode: 0644]
lib/base/eptrlist.h [new file with mode: 0644]
lib/base/estring.cpp [new file with mode: 0644]
lib/base/estring.h [new file with mode: 0644]
lib/base/i18n.h [new file with mode: 0644]
lib/base/init.cpp [new file with mode: 0644]
lib/base/init.h [new file with mode: 0644]
lib/base/init_num.h [new file with mode: 0644]
lib/base/message.cpp [new file with mode: 0644]
lib/base/message.h [new file with mode: 0644]
lib/base/nconfig.cpp [new file with mode: 0644]
lib/base/nconfig.h [new file with mode: 0644]
lib/base/nxml.cpp [new file with mode: 0644]
lib/base/object.h [new file with mode: 0644]
lib/base/ringbuffer.h [new file with mode: 0644]
lib/base/smartptr.cpp [new file with mode: 0644]
lib/base/smartptr.h [new file with mode: 0644]
lib/base/thread.cpp [new file with mode: 0644]
lib/base/thread.h [new file with mode: 0644]
lib/driver/Makefile.am [new file with mode: 0644]
lib/driver/Makefile.in [new file with mode: 0644]
lib/driver/input_fake.h [new file with mode: 0644]
lib/driver/rc.cpp [new file with mode: 0644]
lib/driver/rc.h [new file with mode: 0644]
lib/driver/rcdbox.h [new file with mode: 0644]
lib/driver/rcdreambox2.h [new file with mode: 0644]
lib/driver/rcinput.cpp [new file with mode: 0644]
lib/driver/rcinput.h [new file with mode: 0644]
lib/driver/rfmod.h [new file with mode: 0644]
lib/driver/streamwd.h [new file with mode: 0644]
lib/dvb/Makefile.am [new file with mode: 0644]
lib/dvb/Makefile.in [new file with mode: 0644]
lib/dvb/crc32.cpp [new file with mode: 0644]
lib/dvb/crc32.h [new file with mode: 0644]
lib/dvb/db.cpp [new file with mode: 0644]
lib/dvb/db.h [new file with mode: 0644]
lib/dvb/decoder.cpp [new file with mode: 0644]
lib/dvb/decoder.h [new file with mode: 0644]
lib/dvb/demux.cpp [new file with mode: 0644]
lib/dvb/demux.h [new file with mode: 0644]
lib/dvb/dvb.cpp [new file with mode: 0644]
lib/dvb/dvb.h [new file with mode: 0644]
lib/dvb/esection.cpp [new file with mode: 0644]
lib/dvb/esection.h [new file with mode: 0644]
lib/dvb/frontend.cpp [new file with mode: 0644]
lib/dvb/frontend.h [new file with mode: 0644]
lib/dvb/idvb.h [new file with mode: 0644]
lib/dvb/isection.h [new file with mode: 0644]
lib/dvb/list.h [new file with mode: 0644]
lib/dvb/pmt.cpp [new file with mode: 0644]
lib/dvb/pmt.h [new file with mode: 0644]
lib/dvb/scan.cpp [new file with mode: 0644]
lib/dvb/scan.h [new file with mode: 0644]
lib/dvb/sec.cpp [new file with mode: 0644]
lib/dvb/sec.h [new file with mode: 0644]
lib/dvb/specs.h [new file with mode: 0644]
lib/dvb/stT1RVV7 [new file with mode: 0644]
lib/dvb_si/Makefile.am [new file with mode: 0644]
lib/dvb_si/Makefile.in [new file with mode: 0644]
lib/dvb_si/ac3_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/ac3_descriptor.h [new file with mode: 0644]
lib/dvb_si/ait.cpp [new file with mode: 0644]
lib/dvb_si/ait.h [new file with mode: 0644]
lib/dvb_si/ancillary_data_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/ancillary_data_descriptor.h [new file with mode: 0644]
lib/dvb_si/announcement_support_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/announcement_support_descriptor.h [new file with mode: 0644]
lib/dvb_si/application_signalling_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/application_signalling_descriptor.h [new file with mode: 0644]
lib/dvb_si/audio_stream_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/audio_stream_descriptor.h [new file with mode: 0644]
lib/dvb_si/bat.cpp [new file with mode: 0644]
lib/dvb_si/bat.h [new file with mode: 0644]
lib/dvb_si/bouquet_name_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/bouquet_name_descriptor.h [new file with mode: 0644]
lib/dvb_si/ca_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/ca_descriptor.h [new file with mode: 0644]
lib/dvb_si/ca_identifier_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/ca_identifier_descriptor.h [new file with mode: 0644]
lib/dvb_si/ca_system_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/ca_system_descriptor.h [new file with mode: 0644]
lib/dvb_si/cable_delivery_system_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/cable_delivery_system_descriptor.h [new file with mode: 0644]
lib/dvb_si/camt.cpp [new file with mode: 0644]
lib/dvb_si/camt.h [new file with mode: 0644]
lib/dvb_si/capmt.cpp [new file with mode: 0644]
lib/dvb_si/capmt.h [new file with mode: 0644]
lib/dvb_si/cat.cpp [new file with mode: 0644]
lib/dvb_si/cat.h [new file with mode: 0644]
lib/dvb_si/cell_frequency_link_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/cell_frequency_link_descriptor.h [new file with mode: 0644]
lib/dvb_si/cell_list_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/cell_list_descriptor.h [new file with mode: 0644]
lib/dvb_si/component_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/component_descriptor.h [new file with mode: 0644]
lib/dvb_si/container.cpp [new file with mode: 0644]
lib/dvb_si/container.h [new file with mode: 0644]
lib/dvb_si/content_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/content_descriptor.h [new file with mode: 0644]
lib/dvb_si/copyright_descriptor.h [new file with mode: 0644]
lib/dvb_si/country_availability_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/country_availability_descriptor.h [new file with mode: 0644]
lib/dvb_si/data_broadcast_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/data_broadcast_descriptor.h [new file with mode: 0644]
lib/dvb_si/data_broadcast_id_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/data_broadcast_id_descriptor.h [new file with mode: 0644]
lib/dvb_si/data_stream_alignment_descriptor.h [new file with mode: 0644]
lib/dvb_si/descriptor.cpp [new file with mode: 0644]
lib/dvb_si/descriptor.h [new file with mode: 0644]
lib/dvb_si/descriptor_tag.h [new file with mode: 0644]
lib/dvb_si/dsng_descriptor.h [new file with mode: 0644]
lib/dvb_si/eit.cpp [new file with mode: 0644]
lib/dvb_si/eit.h [new file with mode: 0644]
lib/dvb_si/element_descriptor.h [new file with mode: 0644]
lib/dvb_si/extended_event_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/extended_event_descriptor.h [new file with mode: 0644]
lib/dvb_si/frequency_list_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/frequency_list_descriptor.h [new file with mode: 0644]
lib/dvb_si/group_descriptor.h [new file with mode: 0644]
lib/dvb_si/hierarchy_descriptor.h [new file with mode: 0644]
lib/dvb_si/ibp_descriptor.h [new file with mode: 0644]
lib/dvb_si/ippv_booking_descriptor.h [new file with mode: 0644]
lib/dvb_si/ippv_descriptor.h [new file with mode: 0644]
lib/dvb_si/iso639_language_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/iso639_language_descriptor.h [new file with mode: 0644]
lib/dvb_si/linkage_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/linkage_descriptor.h [new file with mode: 0644]
lib/dvb_si/local_time_offset_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/local_time_offset_descriptor.h [new file with mode: 0644]
lib/dvb_si/long_crc_table.cpp [new file with mode: 0644]
lib/dvb_si/long_crc_table.h [new file with mode: 0644]
lib/dvb_si/long_table.cpp [new file with mode: 0644]
lib/dvb_si/long_table.h [new file with mode: 0644]
lib/dvb_si/maximum_bitrate_descriptor.h [new file with mode: 0644]
lib/dvb_si/mosaic_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/mosaic_descriptor.h [new file with mode: 0644]
lib/dvb_si/multilingual_bouquet_name_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/multilingual_bouquet_name_descriptor.h [new file with mode: 0644]
lib/dvb_si/multilingual_component_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/multilingual_component_descriptor.h [new file with mode: 0644]
lib/dvb_si/multilingual_network_name_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/multilingual_network_name_descriptor.h [new file with mode: 0644]
lib/dvb_si/multilingual_service_name_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/multilingual_service_name_descriptor.h [new file with mode: 0644]
lib/dvb_si/multiplex_buffer_utilization_descriptor.h [new file with mode: 0644]
lib/dvb_si/network_name_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/network_name_descriptor.h [new file with mode: 0644]
lib/dvb_si/nit.cpp [new file with mode: 0644]
lib/dvb_si/nit.h [new file with mode: 0644]
lib/dvb_si/nvod_reference_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/nvod_reference_descriptor.h [new file with mode: 0644]
lib/dvb_si/packet_id.h [new file with mode: 0644]
lib/dvb_si/parental_rating_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/parental_rating_descriptor.h [new file with mode: 0644]
lib/dvb_si/partial_transport_stream_descriptor.h [new file with mode: 0644]
lib/dvb_si/pat.cpp [new file with mode: 0644]
lib/dvb_si/pat.h [new file with mode: 0644]
lib/dvb_si/pdc_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/pdc_descriptor.h [new file with mode: 0644]
lib/dvb_si/pmt.cpp [new file with mode: 0644]
lib/dvb_si/pmt.h [new file with mode: 0644]
lib/dvb_si/private_data_indicator_descriptor.h [new file with mode: 0644]
lib/dvb_si/private_data_specifier_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/private_data_specifier_descriptor.h [new file with mode: 0644]
lib/dvb_si/registration_descriptor.h [new file with mode: 0644]
lib/dvb_si/satellite_delivery_system_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/satellite_delivery_system_descriptor.h [new file with mode: 0644]
lib/dvb_si/sdt.cpp [new file with mode: 0644]
lib/dvb_si/sdt.h [new file with mode: 0644]
lib/dvb_si/service_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/service_descriptor.h [new file with mode: 0644]
lib/dvb_si/service_list_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/service_list_descriptor.h [new file with mode: 0644]
lib/dvb_si/service_move_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/service_move_descriptor.h [new file with mode: 0644]
lib/dvb_si/service_type.h [new file with mode: 0644]
lib/dvb_si/short_crc_table.cpp [new file with mode: 0644]
lib/dvb_si/short_crc_table.h [new file with mode: 0644]
lib/dvb_si/short_event_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/short_event_descriptor.h [new file with mode: 0644]
lib/dvb_si/short_smoothing_buffer_descriptor.h [new file with mode: 0644]
lib/dvb_si/short_table.cpp [new file with mode: 0644]
lib/dvb_si/short_table.h [new file with mode: 0644]
lib/dvb_si/smoothing_buffer_descriptor.h [new file with mode: 0644]
lib/dvb_si/std_descriptor.h [new file with mode: 0644]
lib/dvb_si/stream_identifier_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/stream_identifier_descriptor.h [new file with mode: 0644]
lib/dvb_si/stream_type.h [new file with mode: 0644]
lib/dvb_si/stuffing_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/stuffing_descriptor.h [new file with mode: 0644]
lib/dvb_si/subtitling_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/subtitling_descriptor.h [new file with mode: 0644]
lib/dvb_si/system_clock_descriptor.h [new file with mode: 0644]
lib/dvb_si/table_id.h [new file with mode: 0644]
lib/dvb_si/target_background_grid_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/target_background_grid_descriptor.h [new file with mode: 0644]
lib/dvb_si/tdt.cpp [new file with mode: 0644]
lib/dvb_si/tdt.h [new file with mode: 0644]
lib/dvb_si/telephone_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/telephone_descriptor.h [new file with mode: 0644]
lib/dvb_si/teletext_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/teletext_descriptor.h [new file with mode: 0644]
lib/dvb_si/terrestrial_delivery_system_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/terrestrial_delivery_system_descriptor.h [new file with mode: 0644]
lib/dvb_si/time_shifted_event_descriptor.h [new file with mode: 0644]
lib/dvb_si/time_shifted_service_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/time_shifted_service_descriptor.h [new file with mode: 0644]
lib/dvb_si/tot.cpp [new file with mode: 0644]
lib/dvb_si/tot.h [new file with mode: 0644]
lib/dvb_si/transport_stream_descriptor.h [new file with mode: 0644]
lib/dvb_si/url_descriptor.h [new file with mode: 0644]
lib/dvb_si/vbi_data_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/vbi_data_descriptor.h [new file with mode: 0644]
lib/dvb_si/vbi_teletext_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/vbi_teletext_descriptor.h [new file with mode: 0644]
lib/dvb_si/video_stream_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/video_stream_descriptor.h [new file with mode: 0644]
lib/dvb_si/video_window_descriptor.cpp [new file with mode: 0644]
lib/dvb_si/video_window_descriptor.h [new file with mode: 0644]
lib/gdi/.cvsignore [new file with mode: 0644]
lib/gdi/Makefile.am [new file with mode: 0644]
lib/gdi/epng.cpp [new file with mode: 0644]
lib/gdi/epng.h [new file with mode: 0644]
lib/gdi/epoint.h [new file with mode: 0644]
lib/gdi/erect.cpp [new file with mode: 0644]
lib/gdi/erect.h [new file with mode: 0644]
lib/gdi/esize.h [new file with mode: 0644]
lib/gdi/fb.cpp [new file with mode: 0644]
lib/gdi/fb.h [new file with mode: 0644]
lib/gdi/font.cpp [new file with mode: 0644]
lib/gdi/font.cpp-new [new file with mode: 0644]
lib/gdi/font.h [new file with mode: 0644]
lib/gdi/font_arabic.cpp [new file with mode: 0644]
lib/gdi/gfbdc.cpp [new file with mode: 0644]
lib/gdi/gfbdc.h [new file with mode: 0644]
lib/gdi/glcddc.cpp [new file with mode: 0644]
lib/gdi/glcddc.h [new file with mode: 0644]
lib/gdi/gpixmap.cpp [new file with mode: 0644]
lib/gdi/gpixmap.h [new file with mode: 0644]
lib/gdi/grc.cpp [new file with mode: 0644]
lib/gdi/grc.h [new file with mode: 0644]
lib/gdi/lcd.cpp [new file with mode: 0644]
lib/gdi/lcd.h [new file with mode: 0644]
lib/gui/.cvsignore [new file with mode: 0644]
lib/gui/Makefile.am [new file with mode: 0644]
lib/gui/actions.cpp [new file with mode: 0644]
lib/gui/actions.h [new file with mode: 0644]
lib/gui/combobox.cpp [new file with mode: 0644]
lib/gui/combobox.h [new file with mode: 0644]
lib/gui/decoration.cpp [new file with mode: 0644]
lib/gui/decoration.h [new file with mode: 0644]
lib/gui/ebutton.cpp [new file with mode: 0644]
lib/gui/ebutton.h [new file with mode: 0644]
lib/gui/echeckbox.cpp [new file with mode: 0644]
lib/gui/echeckbox.h [new file with mode: 0644]
lib/gui/elabel.cpp [new file with mode: 0644]
lib/gui/elabel.h [new file with mode: 0644]
lib/gui/emessage.cpp [new file with mode: 0644]
lib/gui/emessage.h [new file with mode: 0644]
lib/gui/enumber.cpp [new file with mode: 0644]
lib/gui/enumber.h [new file with mode: 0644]
lib/gui/epixmap.cpp [new file with mode: 0644]
lib/gui/epixmap.h [new file with mode: 0644]
lib/gui/eprogress.cpp [new file with mode: 0644]
lib/gui/eprogress.h [new file with mode: 0644]
lib/gui/eservicegrid.cpp [new file with mode: 0644]
lib/gui/eservicegrid.h [new file with mode: 0644]
lib/gui/eskin.cpp [new file with mode: 0644]
lib/gui/eskin.h [new file with mode: 0644]
lib/gui/eskin_register.cpp [new file with mode: 0644]
lib/gui/eskin_register.h [new file with mode: 0644]
lib/gui/ewidget.cpp [new file with mode: 0644]
lib/gui/ewidget.h [new file with mode: 0644]
lib/gui/ewindow.cpp [new file with mode: 0644]
lib/gui/ewindow.h [new file with mode: 0644]
lib/gui/guiactions.cpp [new file with mode: 0644]
lib/gui/guiactions.h [new file with mode: 0644]
lib/gui/listbox.cpp [new file with mode: 0644]
lib/gui/listbox.h [new file with mode: 0644]
lib/gui/multipage.cpp [new file with mode: 0644]
lib/gui/multipage.h [new file with mode: 0644]
lib/gui/numberactions.cpp [new file with mode: 0644]
lib/gui/numberactions.h [new file with mode: 0644]
lib/gui/slider.cpp [new file with mode: 0644]
lib/gui/slider.h [new file with mode: 0644]
lib/gui/statusbar.cpp [new file with mode: 0644]
lib/gui/statusbar.h [new file with mode: 0644]
lib/gui/testpicture.cpp [new file with mode: 0644]
lib/gui/testpicture.h [new file with mode: 0644]
lib/gui/textinput.cpp [new file with mode: 0644]
lib/gui/textinput.h [new file with mode: 0644]
lib/network/Makefile.am [new file with mode: 0644]
lib/network/Makefile.in [new file with mode: 0644]
lib/network/http_dyn.cpp [new file with mode: 0644]
lib/network/http_dyn.h [new file with mode: 0644]
lib/network/http_file.cpp [new file with mode: 0644]
lib/network/http_file.h [new file with mode: 0644]
lib/network/httpd.cpp [new file with mode: 0644]
lib/network/httpd.h [new file with mode: 0644]
lib/network/serversocket.cpp [new file with mode: 0644]
lib/network/serversocket.h [new file with mode: 0644]
lib/network/serversocket.lo [new file with mode: 0644]
lib/network/socket.cpp [new file with mode: 0644]
lib/network/socket.h [new file with mode: 0644]
lib/network/socket.lo [new file with mode: 0644]
lib/network/xmlrpc.cpp [new file with mode: 0644]
lib/network/xmlrpc.h [new file with mode: 0644]
lib/service/Makefile.am [new file with mode: 0644]
lib/service/Makefile.in [new file with mode: 0644]
lib/service/iservice.h [new file with mode: 0644]
lib/service/service.cpp [new file with mode: 0644]
lib/service/service.h [new file with mode: 0644]
lib/service/servicedvb.cpp [new file with mode: 0644]
lib/service/servicedvb.h [new file with mode: 0644]
lib/service/servicefs.cpp [new file with mode: 0644]
lib/service/servicefs.h [new file with mode: 0644]
lib/service/servicemp3.cpp [new file with mode: 0644]
lib/service/servicemp3.h [new file with mode: 0644]
main/Makefile.am [new file with mode: 0644]
main/Makefile.in [new file with mode: 0644]
main/enigma-dvbtest.cpp [new file with mode: 0644]
main/enigma-scan.cpp [new file with mode: 0644]
main/enigma.cpp [new file with mode: 0644]
stamp-h.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/DEADJOE b/DEADJOE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..157daf0
--- /dev/null
@@ -0,0 +1,4 @@
+AUTOMAKE_OPTIONS = gnu
+
+SUBDIRS = lib main
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..d646011
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+package="tuxbox-enigma"
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+cd "$srcdir"
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have autoconf installed to compile $package."
+       echo "Download the appropriate package for your system,"
+       echo "or get the source from one of the GNU ftp sites"
+       echo "listed in http://www.gnu.org/order/ftp.html"
+       DIE=1
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have automake installed to compile $package."
+       echo "Download the appropriate package for your system,"
+       echo "or get the source from one of the GNU ftp sites"
+       echo "listed in http://www.gnu.org/order/ftp.html"
+       DIE=1
+}
+
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have libtool installed to compile $package."
+       echo "Download the appropriate package for your system,"
+       echo "or get the source from one of the GNU ftp sites"
+       echo "listed in http://www.gnu.org/order/ftp.html"
+       DIE=1
+}
+
+if test "$DIE" -eq 1; then
+       exit 1
+fi
+
+if [ ! -e acinclude.m4 ]; then
+       for i in .. ../.. ../../..; do
+               if [ -e `pwd`/$i/acinclude.m4 ]; then
+                       ln -s `pwd`/$i/acinclude.m4 .
+               fi
+       done
+fi
+
+echo "Generating configuration files for $package, please wait...."
+
+echo "  aclocal"
+aclocal
+echo "  libtoolize --automake"
+libtoolize --automake
+echo "  autoconf"
+autoconf
+echo "  autoheader"
+autoheader
+echo "  automake --add-missing"
+automake --add-missing 
+
diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/autom4te.cache/requests b/autom4te.cache/requests
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..3224a09
--- /dev/null
@@ -0,0 +1,97 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* where to find the config files */
+#undef CONFIGDIR
+
+/* where to find data like icons */
+#undef DATADIR
+
+/* Enable debug messages */
+#undef DEBUG
+
+/* Define to 1 if translation of program messages to the user's native
+   language is requested. */
+#undef ENABLE_NLS
+
+/* where to find the fonts */
+#undef FONTDIR
+
+/* where games data is stored */
+#undef GAMESDIR
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <linux/dvb/version.h> header file. */
+#undef HAVE_LINUX_DVB_VERSION_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <ost/dmx.h> header file. */
+#undef HAVE_OST_DMX_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* where to find the internal libs */
+#undef LIBDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* where to find the plugins */
+#undef PLUGINDIR
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* where to find the ucodes (firmware) */
+#undef UCODEDIR
+
+/* Version number of package */
+#undef VERSION
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..54d9789
--- /dev/null
@@ -0,0 +1,42 @@
+AC_INIT(tuxbox-enigma,0.0.1)
+AM_INIT_AUTOMAKE(tuxbox-enigma,0.0.1)
+
+TUXBOX_APPS
+TUXBOX_APPS_DIRECTORY
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_RANLIB
+
+TUXBOX_APPS_DVB
+TUXBOX_APPS_DRIVER
+
+TUXBOX_APPS_LIB_CONFIG(FREETYPE,freetype-config)
+TUXBOX_APPS_LIB_PKGCONFIG(FRIBIDI,fribidi)
+TUXBOX_APPS_LIB_PKGCONFIG(ID3TAG,id3tag)
+TUXBOX_APPS_LIB_PKGCONFIG(MAD,mad)
+TUXBOX_APPS_LIB_PKGCONFIG(MD5SUM,tuxbox-md5sum)
+TUXBOX_APPS_LIB_PKGCONFIG(PLUGINS,tuxbox-plugins)
+TUXBOX_APPS_LIB_PKGCONFIG(PNG,libpng)
+TUXBOX_APPS_LIB_PKGCONFIG(SIGC,sigc++-1.2)
+TUXBOX_APPS_LIB_PKGCONFIG(XMLTREE,tuxbox-xmltree)
+
+CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS $FRIBIDI_CFLAGS $ID3TAG_CFLAGS $MAD_CFLAGS $MD5SUM_CFLAGS $PLUGINS_CFLAGS $PNG_CFLAGS $SIGC_CFLAGS $XMLTREE_CFLAGS"
+CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions"
+
+TUXBOX_APPS_GETTEXT
+
+AC_OUTPUT([
+Makefile
+lib/Makefile
+lib/base/Makefile
+lib/driver/Makefile
+lib/dvb/Makefile
+lib/dvb_si/Makefile
+lib/gdi/Makefile
+lib/gui/Makefile
+lib/network/Makefile
+lib/service/Makefile
+main/Makefile
+])
+
diff --git a/debug b/debug
new file mode 100755 (executable)
index 0000000..d9b8771
--- /dev/null
+++ b/debug
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+powerpc-linux-gdb /dbox2/cdkroot/bin/enigma2 -x debug.gdb
+
+
diff --git a/debug.gdb b/debug.gdb
new file mode 100644 (file)
index 0000000..f2b4fca
--- /dev/null
+++ b/debug.gdb
@@ -0,0 +1,3 @@
+set solib-absolute-prefix /dbox2/cdkroot
+target remote 10.0.0.82:1234
+continue
diff --git a/include/connection.h b/include/connection.h
new file mode 100644 (file)
index 0000000..3ccaec1
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __connection_h
+#define __connection_h
+
+#include <libsig_comp.h>
+#include <lib/base/object.h>
+
+class eConnection: public virtual iObject, public Connection
+{
+       int ref;
+public:
+DEFINE_REF(eConnection);
+public:
+       eConnection(const Connection &conn): Connection(conn), ref(0) { };
+       virtual ~eConnection() { disconnect(); }
+};
+
+#endif
diff --git a/include/libsig_comp.h b/include/libsig_comp.h
new file mode 100644 (file)
index 0000000..83550ed
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __LIBSIG_COMP_H
+#define __LIBSIG_COMP_H
+
+#include <sigc++/sigc++.h>
+#include <sigc++/bind.h>
+
+#ifdef SIGC_CXX_NAMESPACES
+using namespace SigC;
+#endif
+
+#define CONNECT(SENDER, EMPFAENGER) SENDER.connect(slot(*this, &EMPFAENGER))
+// use this Makro to connect with a method
+// void bla::foo(int x);
+// to an
+// Signal<void, int> testSig;
+//
+// CONNECT(testSig, bla::foo);
+// signal and method (slot) must have the same signature
+
+#define CONNECT_1_0(SENDER, EMPFAENGER, PARAM) SENDER.connect( bind( slot(*this, &EMPFAENGER) ,PARAM ) )
+// use this for connect with a method
+// void bla::foo(int);
+// to an
+// Signal0<void> testSig;
+// CONNECT_1_0(testSig, bla:foo, 0);
+// here the signal has no parameter, but the slot have an int
+// the last parameter of the CONNECT_1_0 makro is the value that given to the paramater of the Slot method
+
+#define CONNECT_2_0(SENDER, EMPFAENGER, PARAM1, PARAM2) SENDER.connect( bind( slot(*this, &EMPFAENGER) ,PARAM1, PARAM2 ) )
+
+#define CONNECT_2_1(SENDER, EMPFAENGER, PARAM) SENDER.connect( bind( slot(*this, &EMPFAENGER) ,PARAM ) )
+
+#endif // __LIBSIG_COMP_H
diff --git a/lib/DEADJOE b/lib/DEADJOE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644 (file)
index 0000000..7811ca1
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = base  dvb dvb_si gdi  gui  network  service driver 
+
+
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am
new file mode 100644 (file)
index 0000000..3e695a3
--- /dev/null
@@ -0,0 +1,9 @@
+INCLUDES = \
+       -I$(top_srcdir)/include
+
+noinst_LIBRARIES = libenigma_base.a
+
+libenigma_base_a_SOURCES = \
+       buffer.cpp console.cpp ebase.cpp econfig.cpp eerror.cpp elock.cpp \
+       estring.cpp init.cpp message.cpp nconfig.cpp nxml.cpp thread.cpp \
+       smartptr.cpp
diff --git a/lib/base/Makefile.in b/lib/base/Makefile.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/base/a b/lib/base/a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/base/buffer.cpp b/lib/base/buffer.cpp
new file mode 100644 (file)
index 0000000..07e9d7f
--- /dev/null
@@ -0,0 +1,196 @@
+#include <lib/base/buffer.h>
+#include <lib/base/eerror.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+void eIOBuffer::removeblock()
+{
+       ASSERT(!buffer.empty());
+       eIOBufferData &b=buffer.front();
+       delete[] b.data;
+       buffer.pop_front();
+       ptr=0;
+}
+
+eIOBuffer::eIOBufferData &eIOBuffer::addblock()
+{
+       eIOBufferData s;
+       s.data=new __u8[allocationsize];
+       s.len=0;
+       buffer.push_back(s);
+       return buffer.back();
+}
+
+eIOBuffer::~eIOBuffer()
+{
+       clear();
+}
+
+void eIOBuffer::clear()
+{
+       while (!buffer.empty())
+               removeblock();
+}
+
+int eIOBuffer::size() const
+{
+       int total=0;
+       for (std::list<eIOBufferData>::const_iterator i(buffer.begin()); i != buffer.end(); ++i)
+               total+=i->len;
+       total-=ptr;
+       return total;
+}
+
+int eIOBuffer::empty() const
+{
+       return buffer.empty();
+}
+
+int eIOBuffer::peek(void *dest, int len) const
+{
+       __u8 *dst=(__u8*)dest;
+       std::list<eIOBufferData>::const_iterator i(buffer.begin());
+       int p=ptr;
+       int written=0;
+       while (len)
+       {       
+               if (i == buffer.end())
+                       break;
+               int tc=i->len-p;
+               if (tc > len)
+                       tc = len;
+       
+               memcpy(dst, i->data+p, tc);
+               dst+=tc;
+               written+=tc;
+       
+               ++i;
+               p=0;
+                       
+               len-=tc;
+       }
+       return written;
+}
+
+void eIOBuffer::skip(int len)
+{
+       while (len)
+       {
+               ASSERT(! buffer.empty());
+               int tn=len;
+               if (tn > (buffer.front().len-ptr))
+                       tn=buffer.front().len-ptr;
+
+               ptr+=tn;
+               if (ptr == buffer.front().len)
+                       removeblock();
+               len-=tn;
+       }
+}
+
+int eIOBuffer::read(void *dest, int len)
+{
+       __u8 *dst=(__u8*)dest;
+       len=peek(dst, len);
+       skip(len);
+       return len;
+}
+
+void eIOBuffer::write(const void *source, int len)
+{
+       const __u8 *src=(const __u8*)source;
+       while (len)
+       {
+               int tc=len;
+               if (buffer.empty() || (allocationsize == buffer.back().len))
+                       addblock();
+               if (tc > allocationsize-buffer.back().len)
+                       tc=allocationsize-buffer.back().len;
+               memcpy(buffer.back().data+buffer.back().len, src, tc);
+               src+=tc;
+               buffer.back().len+=tc;
+               len-=tc;
+       }
+}
+
+int eIOBuffer::fromfile(int fd, int len)
+{
+       int re=0;
+       while (len)
+       {
+               int tc=len;
+               int r;
+               if (buffer.empty() || (allocationsize == buffer.back().len))
+                       addblock();
+               if (tc > allocationsize-buffer.back().len)
+                       tc=allocationsize-buffer.back().len;
+               r=::read(fd, buffer.back().data+buffer.back().len, tc);
+               buffer.back().len+=r;
+               len-=r;
+               if (r < 0)
+               {
+                       if (errno != EWOULDBLOCK)
+                               eDebug("read: %m");
+                       r=0;
+               }
+               re+=r;
+               if (r != tc)
+                       break;
+       }
+       return re;
+}
+
+int eIOBuffer::tofile(int fd, int len)
+{
+       int written=0;
+       int w;
+       while (len && !buffer.empty())
+       {       
+               if (buffer.begin() == buffer.end())
+                       break;
+               int tc=buffer.front().len-ptr;
+               if (tc > len)
+                       tc = len;
+       
+               w=::write(fd, buffer.front().data+ptr, tc);
+               if (w < 0)
+               {
+                       if (errno != EWOULDBLOCK)
+                               eDebug("write: %m");
+                       w=0;
+               }
+               ptr+=w;
+               if (ptr == buffer.front().len)
+                       removeblock();
+               written+=w;     
+
+               len-=w;
+               if (tc != w)
+                       break;
+       }
+       return written;
+}
+
+int eIOBuffer::searchchr(char ch) const
+{
+       std::list<eIOBufferData>::const_iterator i(buffer.begin());
+       int p=ptr;
+       int c=0;
+       while (1)
+       {       
+               if (i == buffer.end())
+                       break;
+               while (p < i->len)
+               {
+                       if (i->data[p] == ch)
+                               return c;
+                       else
+                               c++, p++;
+               }
+               ++i;
+               p=0;
+       }
+       return -1;
+}
+
diff --git a/lib/base/buffer.h b/lib/base/buffer.h
new file mode 100644 (file)
index 0000000..9108ba8
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __src_lib_base_buffer_h
+#define __src_lib_base_buffer_h
+
+#include <asm/types.h>
+#include <list>
+
+/**
+ * IO buffer.
+ */
+class eIOBuffer
+{
+       int allocationsize;
+       struct eIOBufferData
+       {
+               __u8 *data;
+               int len;
+       };
+       std::list<eIOBufferData> buffer;
+       void removeblock();
+       eIOBufferData &addblock();
+       int ptr;
+public:
+       eIOBuffer(int allocationsize): allocationsize(allocationsize), ptr(0)
+       {
+       }
+       ~eIOBuffer();
+       int size() const;
+       int empty() const;
+       void clear();
+       int peek(void *dest, int len) const;
+       void skip(int len);
+       int read(void *dest, int len);
+       void write(const void *source, int len);
+       int fromfile(int fd, int len);
+       int tofile(int fd, int len);
+
+       int searchchr(char ch) const;
+};
+
+#endif
diff --git a/lib/base/console.cpp b/lib/base/console.cpp
new file mode 100644 (file)
index 0000000..2609582
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * console.cpp
+ *
+ * Copyright (C) 2002 Felix Domke <tmbinc@tuxbox.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: console.cpp,v 1.1 2003-10-17 15:35:47 tmbinc Exp $
+ */
+
+#include <lib/base/console.h>
+
+#include <lib/base/estring.h>
+#include <sys/vfs.h> // for statfs
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+int bidirpipe(int pfd[], char *cmd , char *argv[])
+{
+       int pfdin[2];  /* from child to parent */
+       int pfdout[2]; /* from parent to child */
+       int pfderr[2]; /* stderr from child to parent */
+       int pid;       /* child's pid */
+
+       if ( pipe(pfdin) == -1 || pipe(pfdout) == -1 || pipe(pfderr) == -1)
+               return(-1);
+
+       if ( ( pid = fork() ) == -1 )
+               return(-1);
+       else if (pid == 0) /* child process */
+       {
+               if ( close(0) == -1 || close(1) == -1 || close(2) == -1 )
+                       _exit(0);
+
+               if (dup(pfdout[0]) != 0 || dup(pfdin[1]) != 1 || dup(pfderr[1]) != 2 )
+                       _exit(0);
+
+               if (close(pfdout[0]) == -1 || close(pfdout[1]) == -1 ||
+                               close(pfdin[0]) == -1 || close(pfdin[1]) == -1 ||
+                               close(pfderr[0]) == -1 || close(pfderr[1]) == -1 )
+                       _exit(0);
+
+               execv(cmd,argv);
+               _exit(0);
+       }
+       if (close(pfdout[0]) == -1 || close(pfdin[1]) == -1 || close(pfderr[1]) == -1)
+                       return(-1);
+
+       pfd[0] = pfdin[0];
+       pfd[1] = pfdout[1];
+       pfd[2] = pfderr[0];
+
+       return(pid);
+}
+
+eConsoleAppContainer::eConsoleAppContainer( const eString &cmd )
+:pid(-1), killstate(0), outbuf(0)
+{
+//     eDebug("cmd = %s", cmd.c_str() );
+       memset(fd, 0, sizeof(fd) );
+       int cnt=2; // path to app + terminated 0
+       eString str(cmd?cmd:"");
+
+       while( str.length() && str[0] == ' ' )  // kill spaces at beginning
+               str = str.mid(1);
+
+       while( str.length() && str[str.length()-1] == ' ' )  // kill spaces at the end
+               str = str.left( str.length() - 1 );
+
+       if (!str.length())
+               return;
+
+       unsigned int idx=0;
+       eString path = str.left( (idx = str.find(' ')) != eString::npos ? idx : str.length() );
+//     eDebug("path = %s", path.c_str() );
+
+       eString cmds = str.mid( path.length()+1 );
+//     eDebug("cmds = %s", cmds.c_str() );
+
+       idx = 0;
+       while ( (idx = cmds.find(' ',idx) ) != eString::npos )  // count args
+       {
+               cnt++;
+               idx++;
+       }
+
+//     eDebug("idx = %d, %d counted spaces", idx, cnt-2);
+
+       if ( cmds.length() )
+       {
+               cnt++;
+//             eDebug("increase cnt");
+       }
+
+//     eDebug("%d args", cnt-2);
+       char **argv = new char*[cnt];  // min two args... path and terminating 0
+       argv[0] = new char[ path.length() ];
+       strcpy( argv[0], path.c_str() );
+       argv[cnt-1] = 0;               // set terminating null
+
+       if ( cnt > 2 )  // more then default args?
+       {
+               cnt=1;  // do not overwrite path in argv[0]
+
+               while ( (idx = cmds.find(' ')) != eString::npos )  // parse all args..
+               {
+                       argv[cnt] = new char[ idx ];
+//                     eDebug("idx=%d, arg = %s", idx, cmds.left(idx).c_str() );
+                       strcpy( argv[cnt++], cmds.left( idx ).c_str() );
+                       cmds = cmds.mid(idx+1);
+//                     eDebug("str = %s", cmds.c_str() );
+               }
+               // store the last arg
+               argv[cnt] = new char[ cmds.length() ];
+               strcpy( argv[cnt], cmds.c_str() );
+       }
+
+  // get one read ,one write and the err pipe to the prog..
+  
+       if ( (pid = bidirpipe(fd, argv[0], argv)) == -1 )
+       {
+               while ( cnt-- > 0 )
+                       delete [] argv[cnt];
+               delete [] argv;
+               return;
+       }
+
+       while ( cnt-- > 0 )  // release heap memory
+               delete [] argv[cnt];
+       delete [] argv;
+
+       eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]);
+
+       in = new eSocketNotifier(eApp, fd[0], 19 );  // 19 = POLLIN, POLLPRI, POLLHUP
+       out = new eSocketNotifier(eApp, fd[1], eSocketNotifier::Write);  // POLLOUT
+       err = new eSocketNotifier(eApp, fd[2], 19 );  // 19 = POLLIN, POLLPRI, POLLHUP
+       CONNECT(in->activated, eConsoleAppContainer::readyRead);
+       CONNECT(out->activated, eConsoleAppContainer::readyWrite);
+       CONNECT(err->activated, eConsoleAppContainer::readyErrRead);
+       signal(SIGCHLD, SIG_IGN);   // no zombie when child killed
+}
+
+eConsoleAppContainer::~eConsoleAppContainer()
+{
+       if ( running() )
+       {
+               killstate=-1;
+               kill();
+       }
+       if ( outbuf )
+               delete [] outbuf;
+}
+
+void eConsoleAppContainer::kill()
+{
+       killstate=-1;
+       system( eString().sprintf("kill %d", pid).c_str() );
+       eDebug("user kill console App");
+}
+
+void eConsoleAppContainer::closePipes()
+{
+       in->stop();
+       out->stop();
+       err->stop();
+       ::close(fd[0]);
+       fd[0]=0;
+       ::close(fd[1]);
+       fd[1]=0;
+       ::close(fd[2]);
+       fd[2]=0;
+       eDebug("pipes closed");
+}
+
+void eConsoleAppContainer::readyRead(int what)
+{
+       if (what & POLLPRI|POLLIN)
+       {
+               eDebug("what = %d");
+               char buf[2048];
+               int readed = read(fd[0], buf, 2048);
+               eDebug("%d bytes read", readed);
+               if ( readed != -1 && readed )
+                       /*emit*/ dataAvail( eString( buf ) );
+               else if (readed == -1)
+                       eDebug("readerror %d", errno);
+       }
+       if (what & eSocketNotifier::Hungup)
+       {
+               eDebug("child has terminated");
+               closePipes();
+               /*emit*/ appClosed(killstate);
+       }
+}
+
+void eConsoleAppContainer::readyErrRead(int what)
+{
+       if (what & POLLPRI|POLLIN)
+       {
+               eDebug("what = %d");
+               char buf[2048];
+               int readed = read(fd[2], buf, 2048);
+               eDebug("%d bytes read", readed);
+               if ( readed != -1 && readed )
+                       /*emit*/ dataAvail( eString( buf ) );
+               else if (readed == -1)
+                       eDebug("readerror %d", errno);
+       }
+}
+
+void eConsoleAppContainer::write( const eString & str )
+{
+       outbuf = new char[ str.length()];
+       strcpy( outbuf, str.c_str() );
+}
+
+void eConsoleAppContainer::readyWrite(int what)
+{
+       if (what == 4 && outbuf)
+       {
+               if ( ::write( fd[1], outbuf, strlen(outbuf) ) != (int) strlen(outbuf) )
+               {
+                       /* emit */ dataSent(-1);
+                       eDebug("writeError");
+               }
+               else
+               {
+                       /* emit */ dataSent(0);
+                       eDebug("write ok");
+               }
+
+               delete outbuf;
+               outbuf=0;
+       }
+}
diff --git a/lib/base/console.h b/lib/base/console.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/base/ebase.cpp b/lib/base/ebase.cpp
new file mode 100644 (file)
index 0000000..3babc2e
--- /dev/null
@@ -0,0 +1,206 @@
+#include <lib/base/ebase.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <lib/base/eerror.h>
+
+eSocketNotifier::eSocketNotifier(eMainloop *context, int fd, int requested, bool startnow): context(*context), fd(fd), state(0), requested(requested)
+{
+       if (startnow)   
+               start();
+}
+
+eSocketNotifier::~eSocketNotifier()
+{
+       stop();
+}
+
+void eSocketNotifier::start()
+{
+       if (state)
+               stop();
+
+       context.addSocketNotifier(this);
+       state=1;
+}
+
+void eSocketNotifier::stop()
+{
+       if (state)
+               context.removeSocketNotifier(this);
+
+       state=0;
+}
+
+                                       // timer
+void eTimer::start(long msek, bool singleShot)
+{
+       if (bActive)
+               stop();
+
+       bActive = true;
+       bSingleShot = singleShot;
+       interval = msek;
+       gettimeofday(&nextActivation, 0);               
+//     eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_usec, msek);
+       nextActivation += (msek<0 ? 0 : msek);
+//     eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec );
+       context.addTimer(this);
+}
+
+void eTimer::stop()
+{
+       if (bActive)
+       {
+               bActive=false;
+               context.removeTimer(this);
+       }
+}
+
+void eTimer::changeInterval(long msek)
+{
+       if (bActive)  // Timer is running?
+       {
+               context.removeTimer(this);       // then stop
+               nextActivation -= interval;  // sub old interval
+       }
+       else
+               bActive=true;   // then activate Timer
+
+       interval = msek;                                                // set new Interval
+       nextActivation += interval;             // calc nextActivation
+
+       context.addTimer(this);                         // add Timer to context TimerList
+}
+
+void eTimer::activate()   // Internal Funktion... called from eApplication
+{
+       timeval now;
+       gettimeofday(&now, 0);
+//     eDebug("this = %p\nnow sec = %d, usec = %d\nnextActivation sec = %d, usec = %d", this, now.tv_sec, now.tv_usec, nextActivation.tv_sec, nextActivation.tv_usec );
+//     eDebug("Timer emitted");
+       context.removeTimer(this);
+
+       if (!bSingleShot)
+       {
+               nextActivation += interval;
+               context.addTimer(this);
+       }
+       else
+               bActive=false;
+
+       /*emit*/ timeout();
+}
+
+// mainloop
+
+void eMainloop::addSocketNotifier(eSocketNotifier *sn)
+{
+       notifiers.insert(std::pair<int,eSocketNotifier*> (sn->getFD(), sn));
+}
+
+void eMainloop::removeSocketNotifier(eSocketNotifier *sn)
+{
+       notifiers.erase(sn->getFD());
+}
+
+void eMainloop::processOneEvent()
+{
+// process pending timers...
+       long usec=0;
+
+       while (TimerList && (usec = timeout_usec( TimerList.begin()->getNextActivation() ) ) <= 0 )
+               TimerList.begin()->activate();
+
+       int fdAnz = notifiers.size();
+       pollfd* pfd = new pollfd[fdAnz];  // make new pollfd array
+
+// fill pfd array
+       std::map<int,eSocketNotifier*>::iterator it(notifiers.begin());
+       for (int i=0; i < fdAnz; i++, it++)
+       {
+               pfd[i].fd = it->first;
+               pfd[i].events = it->second->getRequested();
+       }
+
+       int ret=poll(pfd, fdAnz, TimerList ? usec / 1000 : -1);  // milli .. not micro seks
+
+       if (ret>0)
+       {
+//             eDebug("bin aussem poll raus und da war was");
+               for (int i=0; i < fdAnz ; i++)
+               {
+                       if( notifiers.find(pfd[i].fd) == notifiers.end())
+                               continue;
+
+                       int req = notifiers[pfd[i].fd]->getRequested();
+
+                       if ( pfd[i].revents & req )
+                       {
+                               notifiers[pfd[i].fd]->activate(pfd[i].revents);
+
+                               if (!--ret)
+                                       break;
+                       } else if (pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL))
+                               eDebug("poll: unhandled POLLERR/HUP/NVAL for fd %d(%d)", pfd[i].fd,pfd[i].revents);
+               }
+       }
+       else if (ret<0)
+               eDebug("poll made error");
+
+               // check Timers...
+       while ( TimerList && timeout_usec( TimerList.begin()->getNextActivation() ) <= 0 )
+               TimerList.begin()->activate();
+
+       delete [] pfd;
+}
+
+
+int eMainloop::exec()
+{
+       if (!loop_level)
+       {
+               app_quit_now = false;
+               enter_loop();
+       }
+       return retval;
+}
+
+void eMainloop::enter_loop()
+{
+       loop_level++;
+
+       // Status der vorhandenen Loop merken
+       bool old_exit_loop = app_exit_loop;
+       
+       app_exit_loop = false;
+
+       while (!app_exit_loop && !app_quit_now)
+       {
+               processOneEvent();
+       }
+
+       // wiederherstellen der vorherigen app_exit_loop
+       app_exit_loop = old_exit_loop;
+
+       loop_level--;
+
+       if (!loop_level)
+       {
+                       // do something here on exit the last loop
+       }
+}
+
+void eMainloop::exit_loop()  // call this to leave the current loop
+{
+       app_exit_loop = true;   
+}
+
+void eMainloop::quit( int ret )   // call this to leave all loops
+{
+       retval=ret;
+       app_quit_now = true;
+}
+
+eApplication* eApp = 0;
diff --git a/lib/base/ebase.h b/lib/base/ebase.h
new file mode 100644 (file)
index 0000000..b929cb6
--- /dev/null
@@ -0,0 +1,252 @@
+#ifndef __ebase_h
+#define __ebase_h
+
+#include <vector>
+#include <map>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <asm/types.h>
+#include <time.h>
+
+#include <lib/base/eptrlist.h>
+#include <libsig_comp.h>
+
+class eApplication;
+
+extern eApplication* eApp;
+
+static inline bool operator<( const timeval &t1, const timeval &t2 )
+{
+       return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
+}
+
+static inline timeval &operator+=( timeval &t1, const timeval &t2 )
+{
+       t1.tv_sec += t2.tv_sec;
+       if ( (t1.tv_usec += t2.tv_usec) >= 1000000 )
+       {
+               t1.tv_sec++;
+               t1.tv_usec -= 1000000;
+       }
+       return t1;
+}
+
+static inline timeval operator+( const timeval &t1, const timeval &t2 )
+{
+       timeval tmp;
+       tmp.tv_sec = t1.tv_sec + t2.tv_sec;
+       if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 )
+       {
+               tmp.tv_sec++;
+               tmp.tv_usec -= 1000000;
+       }
+       return tmp;
+}
+
+static inline timeval operator-( const timeval &t1, const timeval &t2 )
+{
+       timeval tmp;
+       tmp.tv_sec = t1.tv_sec - t2.tv_sec;
+       if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 )
+       {
+               tmp.tv_sec--;
+               tmp.tv_usec += 1000000;
+       }
+       return tmp;
+}
+
+static inline timeval operator-=( timeval &t1, const timeval &t2 )
+{
+       t1.tv_sec -= t2.tv_sec;
+       if ( (t1.tv_usec -= t2.tv_usec) < 0 )
+       {
+               t1.tv_sec--;
+               t1.tv_usec += 1000000;
+       }
+       return t1;
+}
+
+static inline timeval &operator+=( timeval &t1, const long msek )
+{
+       t1.tv_sec += msek / 1000;
+       if ( (t1.tv_usec += (msek % 1000) * 1000) >= 1000000 )
+       {
+               t1.tv_sec++;
+               t1.tv_usec -= 1000000;
+       }
+       return t1;
+}
+
+static inline timeval operator+( const timeval &t1, const long msek )
+{
+       timeval tmp;
+       tmp.tv_sec = t1.tv_sec + msek / 1000;
+       if ( (tmp.tv_usec = t1.tv_usec + (msek % 1000) * 1000) >= 1000000 )
+       {
+               tmp.tv_sec++;
+               tmp.tv_usec -= 1000000;
+       }
+       return tmp;
+}
+
+static inline timeval operator-( const timeval &t1, const long msek )
+{
+       timeval tmp;
+       tmp.tv_sec = t1.tv_sec - msek / 1000;
+       if ( (tmp.tv_usec = t1.tv_usec - (msek % 1000)*1000) < 0 )
+       {
+               tmp.tv_sec--;
+               tmp.tv_usec += 1000000;
+       }
+       return tmp;
+}
+
+static inline timeval operator-=( timeval &t1, const long msek )
+{
+       t1.tv_sec -= msek / 1000;
+       if ( (t1.tv_usec -= (msek % 1000) * 1000) < 0 )
+       {
+               t1.tv_sec--;
+               t1.tv_usec += 1000000;
+       }
+       return t1;
+}
+
+static inline timeval timeout_timeval ( const timeval & orig )
+{
+       timeval now;
+  gettimeofday(&now,0);
+
+       return orig-now;
+}
+
+static inline long timeout_usec ( const timeval & orig )
+{
+       timeval now;
+  gettimeofday(&now,0);
+
+       return (orig-now).tv_sec*1000000 + (orig-now).tv_usec;
+}
+
+class eMainloop;
+
+                                       // die beiden signalquellen: SocketNotifier...
+
+/**
+ * \brief Gives a callback when data on a file descriptor is ready.
+ *
+ * This class emits the signal \c eSocketNotifier::activate whenever the
+ * event specified by \c req is available.
+ */
+class eSocketNotifier
+{
+public:
+       enum { Read=POLLIN, Write=POLLOUT, Priority=POLLPRI, Error=POLLERR, Hungup=POLLHUP };
+private:
+       eMainloop &context;
+       int fd;
+       int state;
+       int requested;          // requested events (POLLIN, ...)
+public:
+       /**
+        * \brief Constructs a eSocketNotifier.
+        * \param context The thread where to bind the socketnotifier to. The signal is emitted from that thread.
+        * \param fd The filedescriptor to monitor. Can be a device or a socket.
+        * \param req The events to watch to, normally either \c Read or \c Write. You can specify any events that \c poll supports.
+        * \param startnow Specifies if the socketnotifier should start immediately.
+        */
+       eSocketNotifier(eMainloop *context, int fd, int req, bool startnow=true);
+       ~eSocketNotifier();
+
+       Signal1<void, int> activated;
+       void activate(int what) { /*emit*/ activated(what); }
+
+       void start();
+       void stop();
+       bool isRunning() { return state; }
+
+       int getFD() { return fd; }
+       int getRequested() { return requested; }
+       void setRequested(int req) { requested=req; }
+};
+
+                               // ... und Timer
+/**
+ * \brief Gives a callback after a specified timeout.
+ *
+ * This class emits the signal \c eTimer::timeout after the specified timeout.
+ */
+class eTimer
+{
+       eMainloop &context;
+       timeval nextActivation;
+       long interval;
+       bool bSingleShot;
+       bool bActive;
+public:
+       /**
+        * \brief Constructs a timer.
+        *
+        * The timer is not yet active, it has to be started with \c start.
+        * \param context The thread from which the signal should be emitted.
+        */
+       eTimer(eMainloop *context): context(*context), bActive(false) { }
+       ~eTimer()       { if (bActive) stop(); }
+
+       Signal0<void> timeout;
+       void activate();
+
+       bool isActive() { return bActive; }
+       timeval &getNextActivation() { return nextActivation; }
+
+       void start(long msec, bool singleShot=false);
+       void stop();
+       void changeInterval(long msek);
+       bool operator<(const eTimer& t) const   {               return nextActivation < t.nextActivation;               }
+};
+
+                       // werden in einer mainloop verarbeitet
+class eMainloop
+{
+       std::map<int, eSocketNotifier*> notifiers;
+       ePtrList<eTimer> TimerList;
+       bool app_exit_loop;
+       bool app_quit_now;
+       int loop_level;
+       void processOneEvent();
+       int retval;
+public:
+       eMainloop():app_quit_now(0),loop_level(0),retval(0){    }
+       void addSocketNotifier(eSocketNotifier *sn);
+       void removeSocketNotifier(eSocketNotifier *sn);
+       void addTimer(eTimer* e)        {               TimerList.push_back(e);         TimerList.sort();       }
+       void removeTimer(eTimer* e)     {               TimerList.remove(e);    }
+
+       int looplevel() { return loop_level; }
+       
+       int exec();  // recursive enter the loop
+       void quit(int ret=0); // leave all pending loops (recursive leave())
+       void enter_loop();
+       void exit_loop();
+};
+
+/**
+ * \brief The application class.
+ *
+ * An application provides a mainloop, and runs in the primary thread.
+ * You can have other threads, too, but this is the primary one.
+ */
+class eApplication: public eMainloop
+{
+public:
+       eApplication()
+       {
+               if (!eApp)
+                       eApp = this;
+       }
+       ~eApplication()
+       {
+               eApp = 0;
+       }
+};
+#endif
diff --git a/lib/base/econfig.cpp b/lib/base/econfig.cpp
new file mode 100644 (file)
index 0000000..3d51255
--- /dev/null
@@ -0,0 +1,43 @@
+#include <lib/base/eerror.h>
+#include <lib/base/econfig.h>
+#include <lib/base/init.h>
+#include <lib/base/init_num.h>
+#include <sys/stat.h>
+
+eConfig *eConfig::instance;
+
+eConfig::eConfig()
+{
+       if (!instance)
+               instance=this;
+
+       setName(CONFIGDIR "/enigma/registry");
+       int e=open();
+       if (e == NC_ERR_CORRUPT)
+       {
+               eWarning("CORRUTPED REGISTRY!");
+               ::remove(CONFIGDIR "/enigma/registry");
+       }
+       if (e)
+       {
+               if (createNew())
+               {
+                       mkdir(CONFIGDIR "/enigma", 0777);
+                       if (createNew())
+                               eFatal("error while opening/creating registry - create " CONFIGDIR "/enigma");
+               }
+               if (open())
+                       eFatal("still can't open configfile");
+       }
+       locked=1;
+       ppin=0;
+       getKey("/elitedvb/pins/parentallock", ppin );
+}
+
+eConfig::~eConfig()
+{
+       if (instance==this)
+               instance=0;
+}
+
+eAutoInitP0<eConfig> init_eRCConfig(eAutoInitNumbers::configuration, "Configuration");
diff --git a/lib/base/econfig.h b/lib/base/econfig.h
new file mode 100644 (file)
index 0000000..d9f3bec
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __econfig_h
+#define __econfig_h
+
+#include <lib/base/nconfig.h>
+
+class eConfig: public NConfig
+{
+       static eConfig *instance;
+       int ppin;
+public:
+       int locked;
+       static eConfig *getInstance() { return instance; }
+       void setParentalPin( int pin )
+       {
+                ppin = pin;
+                setKey("/elitedvb/pins/parentallock", ppin );
+       }
+       int getParentalPin() { return ppin; }
+       bool pLockActive()
+       {
+               return ppin && locked;
+       }
+       eConfig();
+       ~eConfig();
+};
+
+#endif
diff --git a/lib/base/eerror.cpp b/lib/base/eerror.cpp
new file mode 100644 (file)
index 0000000..0871bb7
--- /dev/null
@@ -0,0 +1,69 @@
+#include <lib/base/eerror.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <lib/gui/emessage.h>
+
+int infatal=0;
+
+Signal2<void, int, const eString&> logOutput;
+int logOutputConsole=1;
+
+void eFatal(const char* fmt, ...)
+{
+       char buf[1024];
+       va_list ap;
+       va_start(ap, fmt);
+       vsnprintf(buf, 1024, fmt, ap);
+       va_end(ap);
+       logOutput(lvlFatal, buf);
+       fprintf(stderr, "%s\n",buf );
+       if (!infatal)
+       {
+               infatal=1;
+               eMessageBox msg(buf, "FATAL ERROR", eMessageBox::iconError|eMessageBox::btOK);
+               msg.show();
+               msg.exec();
+       }
+       _exit(0);
+}
+
+#ifdef DEBUG
+void eDebug(const char* fmt, ...)
+{
+       char buf[1024];
+       va_list ap;
+       va_start(ap, fmt);
+       vsnprintf(buf, 1024, fmt, ap);
+       va_end(ap);
+       logOutput(lvlDebug, eString(buf) + "\n");
+       if (logOutputConsole)
+               fprintf(stderr, "%s\n", buf);
+}
+
+void eDebugNoNewLine(const char* fmt, ...)
+{
+       char buf[1024];
+       va_list ap;
+       va_start(ap, fmt);
+       vsnprintf(buf, 1024, fmt, ap);
+       va_end(ap);
+       logOutput(lvlDebug, buf);
+       if (logOutputConsole)
+               fprintf(stderr, "%s", buf);
+}
+
+void eWarning(const char* fmt, ...)
+{
+       char buf[1024];
+       va_list ap;
+       va_start(ap, fmt);
+       vsnprintf(buf, 1024, fmt, ap);
+       va_end(ap);
+       logOutput(lvlWarning, eString(buf) + "\n");
+       if (logOutputConsole)
+               fprintf(stderr, "%s\n", buf);
+}
+#endif // DEBUG
diff --git a/lib/base/eerror.h b/lib/base/eerror.h
new file mode 100644 (file)
index 0000000..bf91395
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __E_ERROR__
+#define __E_ERROR__
+
+#include "config.h"
+#include <string>
+#include <map>       
+#include <new>
+#include <libsig_comp.h>
+
+void eFatal(const char* fmt, ...);
+
+class eString;
+
+enum { lvlDebug=1, lvlWarning=2, lvlFatal=4 };
+
+extern Signal2<void, int, const eString&> logOutput;
+extern int logOutputConsole;
+
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifdef DEBUG
+    void eDebug(const char* fmt, ...);
+    void eDebugNoNewLine(const char* fmt, ...);
+    void eWarning(const char* fmt, ...);
+    #define ASSERT(x) { if (!(x)) eFatal("%s:%d ASSERTION %s FAILED!", __FILE__, __LINE__, #x); }
+#else
+    inline void eDebug(const char* fmt, ...)
+    {
+    }
+
+    inline void eDebugNoNewLine(const char* fmt, ...)
+    {
+    }
+
+    inline void eWarning(const char* fmt, ...)
+    {
+    }
+    #define ASSERT(x) do { } while (0)
+#endif //DEBUG
+
+#endif // __E_ERROR__
diff --git a/lib/base/elock.cpp b/lib/base/elock.cpp
new file mode 100644 (file)
index 0000000..afddcc6
--- /dev/null
@@ -0,0 +1,104 @@
+#include <lib/base/elock.h>
+#include <unistd.h>
+
+void eLock::lock(int res)
+{
+       if (res>max)
+               res=max;
+       pthread_mutex_lock(&mutex);
+       while ((counter+res)>max)
+               pthread_cond_wait(&cond, &mutex);
+       counter+=res;
+       pthread_mutex_unlock(&mutex);
+}
+
+void eLock::unlock(int res)
+{
+       if (res>max)
+               res=max;
+       pthread_mutex_lock(&mutex);
+       counter-=res;
+       pthread_mutex_unlock(&mutex);
+       pthread_cond_signal(&cond);
+}
+
+eLock::eLock(int max): max(max)
+{
+       pthread_mutex_init(&mutex, 0);
+       pthread_cond_init(&cond, 0);
+       counter=0;
+       pid=-1;
+}
+
+eLock::~eLock()
+{
+       pthread_mutex_destroy(&mutex);
+       pthread_cond_destroy(&cond);
+}
+
+eLocker::eLocker(eLock &lock, int res): lock(lock), res(res)
+{
+       lock.lock(res);
+}
+
+eLocker::~eLocker()
+{
+       lock.unlock(res);
+}
+
+eSemaphore::eSemaphore()
+{
+       v=1;
+       pthread_mutex_init(&mutex, 0);
+       pthread_cond_init(&cond, 0);
+}
+
+eSemaphore::~eSemaphore()
+{
+       pthread_mutex_destroy(&mutex);
+       pthread_cond_destroy(&cond);
+}
+
+int eSemaphore::down()
+{
+       int value_after_op;
+       pthread_mutex_lock(&mutex);
+       while (v<=0)
+               pthread_cond_wait(&cond, &mutex);
+       v--;
+       value_after_op=v;
+       pthread_mutex_unlock(&mutex);
+       return value_after_op;
+}
+
+int eSemaphore::decrement()
+{
+       int value_after_op;
+       pthread_mutex_lock(&mutex);
+       v--;
+       value_after_op=v;
+       pthread_mutex_unlock(&mutex);
+       pthread_cond_signal(&cond);
+       return value_after_op;
+}
+
+int eSemaphore::up()
+{
+       int value_after_op;
+       pthread_mutex_lock(&mutex);
+       v++;
+       value_after_op=v;
+       pthread_mutex_unlock(&mutex);
+       pthread_cond_signal(&cond);
+       return value_after_op;
+}
+
+int eSemaphore::value()
+{
+       int value_after_op;
+       pthread_mutex_lock(&mutex);
+       value_after_op=v;
+       pthread_mutex_unlock(&mutex);
+       return value_after_op;
+}
+
diff --git a/lib/base/elock.h b/lib/base/elock.h
new file mode 100644 (file)
index 0000000..6a47f8c
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __elock_h
+#define __elock_h
+
+#include <pthread.h>
+
+class singleLock
+{
+       pthread_mutex_t &lock;
+public:
+       singleLock( pthread_mutex_t &m )
+               :lock(m)
+       {
+               pthread_mutex_lock(&lock);
+       }
+       ~singleLock()
+       {
+               pthread_mutex_unlock(&lock);
+       }
+};
+
+class eLock
+{
+       pthread_mutex_t mutex;
+       pthread_cond_t cond;
+
+       int pid;
+       int counter, max;
+public:
+       void lock(int res=100);
+       void unlock(int res=100);
+
+       eLock(int max=100);
+       ~eLock();
+};
+
+class eLocker
+{
+       eLock &lock;
+       int res;
+public:
+       eLocker(eLock &lock, int res=100);
+       ~eLocker();
+};
+
+class eSemaphore
+{
+       int v;
+       pthread_mutex_t mutex;
+       pthread_cond_t cond;
+public:
+       eSemaphore();
+       ~eSemaphore();
+       
+       int down();
+       int decrement();
+       int up();
+       int value();
+};
+
+#endif
diff --git a/lib/base/eptrlist.h b/lib/base/eptrlist.h
new file mode 100644 (file)
index 0000000..f1421eb
--- /dev/null
@@ -0,0 +1,1338 @@
+#ifndef _E_PTRLIST_
+#define _E_PTRLIST_
+
+#include <list>
+#include <vector>
+#include <lib/base/smartptr.h>
+
+template <class T>
+class ePtrList : public std::list<T*>
+{
+public:
+       typedef typename std::list<T*, std::allocator<T*> >::iterator std_list_T_iterator;  // to remove compiler warnings
+       typedef typename std::list<T*, std::allocator<T*> >::const_iterator std_list_T_const_iterator;
+       typedef typename std::list<T*, std::allocator<T*> >::reverse_iterator std_list_T_reverse_iterator;
+       typedef typename std::list<T*, std::allocator<T*> >::const_reverse_iterator std_list_T_const_reverse_iterator;
+       typedef typename ePtrList<T>::iterator T_iterator;
+       typedef typename ePtrList<T>::const_iterator T_const_iterator;
+       typedef typename ePtrList<T>::reverse_iterator T_reverse_iterator;
+       typedef typename ePtrList<T>::const_reverse_iterator T_const_reverse_iterator;
+
+// Iterator classes
+       class iterator;
+       class const_iterator;
+       class reverse_iterator;
+       class const_reverse_iterator;
+
+// Constructors
+       inline ePtrList();
+       inline ePtrList(const ePtrList&);
+       inline ~ePtrList();
+
+// overwritted sort method
+       inline void sort();
+
+// changed methods for autodelete and current implementation
+       inline void remove(T* t);
+       inline void clear();
+       inline void pop_back();
+       inline void pop_front();
+       inline void push_back(T*);
+       inline void push_front(T*);
+
+// added methods for current implementation
+       inline T* take();
+       inline void take(T* t);
+       inline T* current();
+       inline T* next();
+       inline T* prev();
+       inline T* first();
+       inline T* last();
+       inline T* setCurrent(const T*);
+       inline const T* current() const;
+       inline const T* next() const;
+       inline const T* prev() const;
+       inline const T* first() const;
+       inline const T* last() const;
+
+// added operator methods
+       inline operator bool();
+       inline bool operator!();
+
+// added methods for autodelete implementation
+       inline void setAutoDelete(bool b);
+       inline bool isAutoDelete();
+
+// added compare struct ... to sort
+       struct less;
+private:
+       iterator cur;
+       bool autoDelete;
+
+public:
+       iterator ePtrList<T>::begin()
+       {                               
+       //      makes implicit type conversion form std::list::iterator to ePtrList::iterator
+               return std::list<T*>::begin();          
+       }
+
+       iterator ePtrList<T>::end()
+       {                               
+       //      makes implicit type conversion form std::list::iterator to ePtrList::iterator
+               return std::list<T*>::end();            
+       }
+
+       const_iterator ePtrList<T>::begin() const
+       {                               
+       //      makes implicit type conversion form std::list::const_iterator to ePtrList::const_iterator
+               return std::list<T*>::begin();          
+       }
+
+       const_iterator ePtrList<T>::end() const
+       {                               
+       //      makes implicit type conversion form std::list::const_iterator to ePtrList::const_iterator
+               return std::list<T*>::end();            
+       }
+
+       reverse_iterator ePtrList<T>::rbegin()
+       {                               
+       //      makes implicit type conversion form std::list::reverse:_iterator to ePtrList::reverse_iterator
+               return std::list<T*>::rbegin();         
+       }
+
+       reverse_iterator ePtrList<T>::rend()
+       {                               
+       //      makes implicit type conversion form std::list::reverse_iterator to ePtrList::reverse_iterator
+               return std::list<T*>::rend();           
+       }
+
+       const_reverse_iterator ePtrList<T>::rbegin() const
+       {                               
+       //      makes implicit type conversion form std::list::const_reverse_iterator to ePtrList::const_reverse_iterator
+               return std::list<T*>::rbegin();         
+       }
+
+       const_reverse_iterator ePtrList<T>::rend() const
+       {                               
+       //      makes implicit type conversion form std::list::const_reverse_iterator to ePtrList::const_reverse_iterator
+               return std::list<T*>::rend();           
+       }
+
+       iterator ePtrList<T>::erase(iterator it)
+       {
+       //      Remove the item it, if auto-deletion is enabled, than the list call delete for this item
+       //  If current is equal to the item that was removed, current is set to the next item in the list
+               if (autoDelete && *it)
+                       delete *it;                                     
+
+               if (cur == it)
+                       return cur = std::list<T*>::erase(it);
+               else
+                       return std::list<T*>::erase(it);
+       }
+
+       iterator ePtrList<T>::erase(iterator from, iterator to)
+       {
+       //      Remove all items between the to iterators from and to
+       //      If auto-deletion is enabled, than the list call delete for all removed items
+               while (from != to)
+                       from = erase(from);
+       
+               return from;
+       }
+
+       operator iterator()     
+       {
+       //      Returns a iterator that equal to begin() of the list
+               return begin(); 
+       }
+
+       operator const_iterator() const
+       {
+       //      Returns a const_iterator that equal to begin() of the list
+               return begin(); 
+       }
+
+       operator reverse_iterator()
+       {
+       //      Returns a reverse_iterator that equal to rbegin() of the list
+               return rbegin();        
+       }
+
+       operator const_reverse_iterator() const 
+       {
+       //      Returns a const_reverse_iterator that equal to rbegin() of the list
+               return rbegin();        
+       }
+
+       std::vector<T>* getVector()
+       {
+               // Creates an vector and copys all elements to this vector
+               // returns a pointer to this new vector ( the reserved memory must deletet from the receiver !! )
+               std::vector<T>* v=new std::vector<T>();
+               v->reserve( size() );
+    for ( std_list_T_iterator it( std::list<T*>::begin() ); it != std::list<T*>::end(); it++)
+                       v->push_back( **it );
+
+               return v;
+       }
+
+       inline iterator insert_in_order( T* e )
+       {
+               // added a new item to the list... in order
+               // returns a iterator to the new item
+               return insert( std::lower_bound( std::list<T*>::begin(), std::list<T*>::end(), e ), e );
+       }
+
+};
+
+/////////////////// iterator class /////////////////////////////
+template <class T>
+class ePtrList<T>::iterator : public std::list<T*>::iterator
+{
+public:
+       // Constructors
+       iterator(const std_list_T_iterator& Q)          : std_list_T_iterator(Q)        {       }
+
+       // changed operator for pointer
+       T* operator->() const
+       {
+               return *std::list<T*>::iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+       
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       iterator& operator++()
+       {
+               std::list<T*>::iterator::operator++();
+               return *this;
+       }
+
+       iterator operator++(int)
+       {
+               return std::list<T*>::iterator::operator++(0);
+       }
+
+       iterator& operator--()
+       {
+               std::list<T*>::iterator::operator--();
+               return *this;
+       }
+
+       iterator operator--(int)
+       {
+               return std::list<T*>::iterator::operator--(0);
+       }
+};
+
+/////////////////// const_iterator class /////////////////////////////
+template <class T>
+class ePtrList<T>::const_iterator : public std::list<T*>::const_iterator
+{
+public:
+       // Constructors
+       const_iterator(const std_list_T_const_iterator& Q)              :std_list_T_const_iterator(Q)   {       }
+
+       // changed operator for pointer
+       T* operator->() const
+       {
+               return *std::list<T*>::const_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       const_iterator& operator++()
+       {
+               std::list<T*>::const_iterator::operator++();
+               return *this;
+       }
+
+       const_iterator operator++(int)
+       {
+               return std::list<T*>::const_iterator::operator++(0);
+       }
+
+       const_iterator& operator--()
+       {
+               std::list<T*>::const_iterator::operator--();
+               return *this;
+       }
+
+       const_iterator operator--(int)
+       {
+               return std::list<T*>::const_iterator::operator--(0);
+       }
+};
+
+/////////////////// reverse_iterator class /////////////////////////////
+template <class T>
+class ePtrList<T>::reverse_iterator : public std::list<T*>::reverse_iterator
+{
+public:
+       // Constructors
+       reverse_iterator(const std_list_T_reverse_iterator& Q)          :std_list_T_reverse_iterator(Q) {       }
+
+       // changed operators for pointer
+       T* operator->() const
+       {
+               return *std::list<T*>::reverse_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       reverse_iterator& operator++()
+       {
+               std::list<T*>::reverse_iterator::operator++();
+               return *this;
+       }
+
+       reverse_iterator operator++(int)
+       {
+               return std::list<T*>::reverse_iterator::operator++(0);
+       }
+
+       reverse_iterator& operator--()
+       {
+               std::list<T*>::reverse_iterator::operator--();
+               return *this;
+       }
+
+       reverse_iterator operator--(int)
+       {
+               return std::list<T*>::reverse_iterator::operator--(0);
+       }
+};
+
+/////////////////// const_reverse_iterator class /////////////////////////////
+template <class T>
+class ePtrList<T>::const_reverse_iterator : public std::list<T*>::const_reverse_iterator
+{
+public:
+       // Constructors
+       const_reverse_iterator(const std_list_T_const_reverse_iterator& Q)              :std_list_T_const_reverse_iterator(Q)   {       }
+
+       // changed operators for pointer
+       T* operator->() const
+       {
+               return *std::list<T*>::const_reverse_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       const_reverse_iterator& operator++()
+       {
+               std::list<T*>::const_reverse_iterator::operator++();
+               return *this;
+       }
+
+       const_reverse_iterator operator++(int)
+       {
+               return std::list<T*>::const_reverse_iterator::operator++(0);
+       }
+
+       const_reverse_iterator& operator--()
+       {
+               std::list<T*>::const_reverse_iterator::operator--();
+               return *this;
+       }
+
+       const_reverse_iterator operator--(int)
+       {
+               return std::list<T*>::const_reverse_iterator::operator--(0);
+       }
+};
+
+/////////////////// Default Constructor /////////////////////////////
+template <class T>
+ePtrList<T>::ePtrList()
+    :cur(std::list<T*>::begin()), autoDelete(false)            
+{              
+
+}
+
+/////////////////// Copy Constructor /////////////////////////////
+template <class T>
+ePtrList<T>::ePtrList(const ePtrList& e)
+       :std::list<T*>(e), cur(e.cur), autoDelete( false )
+{              
+       if ( e.autoDelete )     
+               if ( e.size() )
+                       eDebug("Warning !! We make a Copy of a non empty ePtrList, with autoDelete enabled"
+                                                "We disable autoDelete in the new ePtrList !!");
+               else
+                       autoDelete=true;
+}
+
+/////////////////// ePtrList Destructor /////////////////////////////
+template <class T>
+inline ePtrList<T>::~ePtrList()
+{
+// if autoDelete is enabled, delete is called for all elements in the list
+       if (autoDelete)
+               for (std_list_T_iterator it(std::list<T*>::begin()); it != std::list<T*>::end(); it++)
+                       delete *it;
+}
+
+
+/////////////////// ePtrList sort() /////////////////////////
+template <class T>
+inline void ePtrList<T>::sort()
+{              
+//     Sorts all items in the list.
+//     The type T must have a operator <.
+       std::list<T*>::sort(ePtrList<T>::less());
+}      
+
+/////////////////// ePtrList remove(T*) /////////////////////////
+template <class T>
+inline void ePtrList<T>::remove(T* t)
+{
+//     Remove all items that, equals to t, if auto-deletion is enabled, than the list call delete for the removed items
+//  If current is equal to one of the removed items, current is set to the next valid item
+       T_iterator it(std::list<T*>::begin());
+
+       while (it != std::list<T*>::end())
+               if (*it == t)
+               {
+                       it=erase(it);
+                       break;  // one item is complete removed an deleted
+               }
+               else
+                       it++;
+       
+       while (it != std::list<T*>::end())
+               if (*it == t)
+                       it = std::list<T*>::erase(it);  // remove all other items that equals to t (no delete is called..)
+               else
+                       it++;
+                       
+}
+
+/////////////////// ePtrList clear() //////////////////
+template <class T>
+inline void ePtrList<T>::clear()       
+{              
+//     Remove all items from the list
+//     If auto-deletion is enabled, than the list call delete for all items in the list
+       erase(std::list<T*>::begin(), std::list<T*>::end());    
+}
+
+/////////////////// ePtrList pop_back() ////////////////////
+template <class T>
+inline void ePtrList<T>::pop_back()
+{
+//     Removes the last item from the list. If the current item ist the last, than the current is set to the new
+//     last item in the list;
+//     The removed item is deleted if auto-deletion is enabled.
+       erase(--end());
+}
+
+/////////////////// ePtrList pop_front() ////////////////////
+template <class T>
+inline void ePtrList<T>::pop_front()
+{
+//     Removes the first item from the list. If the current item ist the first, than the current is set to the new
+//     first item in the list;
+//     The removed item is deleted if auto-deletion is enabled.
+       erase(begin());
+}
+
+/////////////////// ePtrList push_back(T*) ////////////////////
+template <class T>
+inline void ePtrList<T>::push_back(T* x)       
+{              
+// Add a new item at the end of the list.
+// The current item is set to the last item;
+       std::list<T*>::push_back(x);
+       last(); 
+}
+
+/////////////////// ePtrList push_front(T*) ////////////////////
+template <class T>
+inline void ePtrList<T>::push_front(T* x)      
+{              
+// Add a new item at the begin of the list.
+// The current item is set to the first item;
+       std::list<T*>::push_front(x);
+       first();        
+}
+
+/////////////////// ePtrList take() ////////////////////
+template <class T>
+inline T* ePtrList<T>::take()
+{
+// Takes the current item out of the list without deleting it (even if auto-deletion is enabled).
+// Returns a pointer to the item taken out of the list, or null if the index is out of range.
+// The item after the taken item becomes the new current list item if the taken item is not the last item in the list. If the last item is taken, the new last item becomes the current item.
+// The current item is set to null if the list becomes empty.
+       T* tmp = *cur;
+       cur = std::list<T*>::erase(cur);
+       return tmp;
+}
+
+/////////////////// ePtrList take(T*) ////////////////////
+template <class T>
+inline void ePtrList<T>::take(T* t)
+{
+// Takes all item with T* out of the list without deleting it (even if auto-deletion is enabled).
+       std::list<T*>::remove(t);
+}
+
+/////////////////// ePtrList setCurrent(T*) ////////////////////
+template <class T>
+inline T* ePtrList<T>::setCurrent(const T* t)
+{
+       // Sets the internal current iterator to the first element that equals to t, and returns t when a item is found,
+       // otherwise it returns 0 !
+       for (T_iterator it(std::list<T*>::begin()); it != std::list<T*>::end(); ++it)
+               if (*it == t)
+               {
+                       cur = it;
+                       return *it;
+               }
+
+       return 0;
+}
+
+/////////////////// ePtrList current() ////////////////////
+template <class T>
+inline T* ePtrList<T>::current()
+{
+//     Returns a pointer to the current list item. The current item may be null (implies that the current index is -1).
+       return cur==end() ? 0 : *cur;   
+}
+
+/////////////////// ePtrList next() ////////////////////
+template <class T>
+inline T* ePtrList<T>::next()
+{
+//     Returns a pointer to the item succeeding the current item. Returns null if the current items is null or equal to the last item.
+//     Makes the succeeding item current. If the current item before this function call was the last item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == end())
+               return 0;
+       else
+               if (++cur == end())
+                       return 0;
+               else
+                       return *cur;
+}
+
+/////////////////// ePtrList prev() ////////////////////
+template <class T>
+inline T* ePtrList<T>::prev()
+{
+//     Returns a pointer to the item preceding the current item. Returns null if the current items is null or equal to the first item.
+//     Makes the preceding item current. If the current item before this function call was the first item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == begin())
+               return 0;
+       else
+               return *--cur;
+}
+
+/////////////////// ePtrList first() ////////////////////
+template <class T>
+inline T* ePtrList<T>::first()
+{
+// Returns a pointer to the first item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = begin());        
+}
+
+/////////////////// ePtrList last() ////////////////////
+template <class T>
+inline T* ePtrList<T>::last()
+{
+//     Returns a pointer to the last item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = --end());
+}
+
+/////////////////// const ePtrList current() ////////////////////
+template <class T>
+inline const T* ePtrList<T>::current() const
+{
+//     Returns a pointer to the current list item. The current item may be null (implies that the current index is not valid)
+       return cur==end() ? 0 : *cur;   
+}
+
+/////////////////// const ePtrList next() ////////////////////
+template <class T>
+inline const T* ePtrList<T>::next() const
+{
+//     Returns a pointer to the item succeeding the current item. Returns null if the current items is null or equal to the last item.
+//     Makes the succeeding item current. If the current item before this function call was the last item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == end())
+               return 0;
+       else
+               if (++cur == end())
+                       return 0;
+               else
+                       return *cur;
+}
+
+/////////////////// const ePtrList prev() ////////////////////
+template <class T>
+inline const T* ePtrList<T>::prev() const
+{
+//     Returns a pointer to the item preceding the current item. Returns null if the current items is null or equal to the first item.
+//     Makes the preceding item current. If the current item before this function call was the first item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == begin())
+               return 0;
+       else
+               return *--cur;
+}
+
+/////////////////// const ePtrList first() ////////////////////
+template <class T>
+inline const T* ePtrList<T>::first() const
+{
+// Returns a pointer to the first item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = begin());        
+}
+
+/////////////////// const ePtrList last() ////////////////////
+template <class T>
+inline const T* ePtrList<T>::last() const
+{
+//     Returns a pointer to the last item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = --end());
+}
+
+////////////////// struct less //////////////////////////////
+template <class T>
+struct ePtrList<T>::less
+{
+//     operator() is used internal from the list to sort them
+       bool operator() (const T* t1, const T* t2)
+       {
+               return (*t1 < *t2);
+       }
+};
+
+/////////////////// ePtrList operator bool ////////////////////
+template <class T>
+ePtrList<T>::operator bool()   
+{
+//     Returns a bool that contains true, when the list is NOT empty otherwise false
+       return !empty();        
+}
+
+template <class T>
+bool ePtrList<T>::operator!()  
+{
+//     Returns a bool that contains true, when the list is empty otherwise false
+       return empty(); 
+}
+
+template <class T>
+void ePtrList<T>::setAutoDelete(bool b)
+{
+//     switched autoDelete on or off
+//     if autoDelete is true, than the pointer list controls the heap memory behind the pointer itself
+//     the list calls delete for the item before it removed from the list
+       autoDelete=b;   
+}
+
+template <class T>
+bool ePtrList<T>::isAutoDelete()
+{
+// returns a bool that contains the state of autoDelete
+       return autoDelete;
+}
+
+template <class T>
+class eSmartPtrList : public std::list<ePtr<T> >
+{
+public:
+       typedef typename std::list<ePtr<T>, std::allocator<ePtr<T> > >::iterator std_list_T_iterator;  // to remove compiler warnings
+       typedef typename std::list<ePtr<T>, std::allocator<ePtr<T> > >::const_iterator std_list_T_const_iterator;
+       typedef typename std::list<ePtr<T>, std::allocator<ePtr<T> > >::reverse_iterator std_list_T_reverse_iterator;
+       typedef typename std::list<ePtr<T>, std::allocator<ePtr<T> > >::const_reverse_iterator std_list_T_const_reverse_iterator;
+       typedef typename eSmartPtrList<T>::iterator T_iterator;
+       typedef typename eSmartPtrList<T>::const_iterator T_const_iterator;
+       typedef typename eSmartPtrList<T>::reverse_iterator T_reverse_iterator;
+       typedef typename eSmartPtrList<T>::const_reverse_iterator T_const_reverse_iterator;
+
+// Iterator classes
+       class iterator;
+       class const_iterator;
+       class reverse_iterator;
+       class const_reverse_iterator;
+
+// Constructors
+       inline eSmartPtrList();
+       inline eSmartPtrList(const eSmartPtrList&);
+       inline ~eSmartPtrList();
+
+// overwritted sort method
+       inline void sort();
+
+// changed methods for autodelete and current implementation
+       inline void remove(T* t);
+       inline void clear();
+       inline void pop_back();
+       inline void pop_front();
+       inline void push_back(T*);
+       inline void push_front(T*);
+
+// added methods for current implementation
+//     inline T* take();
+//     inline void take(T* t);
+       inline T* current();
+       inline T* next();
+       inline T* prev();
+       inline T* first();
+       inline T* last();
+       inline T* setCurrent(const T*);
+       inline const T* current() const;
+       inline const T* next() const;
+       inline const T* prev() const;
+       inline const T* first() const;
+       inline const T* last() const;
+
+// added operator methods
+       inline operator bool();
+       inline bool operator!();
+
+// added methods for autodelete implementation
+       inline void setAutoDelete(bool b);
+       inline bool isAutoDelete();
+
+// added compare struct ... to sort
+       struct less;
+private:
+       iterator cur;
+       bool autoDelete;
+
+public:
+       iterator eSmartPtrList<T>::begin()
+       {                               
+       //      makes implicit type conversion form std::list::iterator to eSmartPtrList::iterator
+               return std::list<ePtr<T> >::begin();            
+       }
+
+       iterator eSmartPtrList<T>::end()
+       {                               
+       //      makes implicit type conversion form std::list::iterator to eSmartPtrList::iterator
+               return std::list<ePtr<T> >::end();              
+       }
+
+       const_iterator eSmartPtrList<T>::begin() const
+       {                               
+       //      makes implicit type conversion form std::list::const_iterator to eSmartPtrList::const_iterator
+               return std::list<ePtr<T> >::begin();            
+       }
+
+       const_iterator eSmartPtrList<T>::end() const
+       {                               
+       //      makes implicit type conversion form std::list::const_iterator to eSmartPtrList::const_iterator
+               return std::list<ePtr<T> >::end();              
+       }
+
+       reverse_iterator eSmartPtrList<T>::rbegin()
+       {                               
+       //      makes implicit type conversion form std::list::reverse:_iterator to eSmartPtrList::reverse_iterator
+               return std::list<ePtr<T> >::rbegin();           
+       }
+
+       reverse_iterator eSmartPtrList<T>::rend()
+       {                               
+       //      makes implicit type conversion form std::list::reverse_iterator to eSmartPtrList::reverse_iterator
+               return std::list<ePtr<T> >::rend();             
+       }
+
+       const_reverse_iterator eSmartPtrList<T>::rbegin() const
+       {                               
+       //      makes implicit type conversion form std::list::const_reverse_iterator to eSmartPtrList::const_reverse_iterator
+               return std::list<ePtr<T> >::rbegin();           
+       }
+
+       const_reverse_iterator eSmartPtrList<T>::rend() const
+       {                               
+       //      makes implicit type conversion form std::list::const_reverse_iterator to eSmartPtrList::const_reverse_iterator
+               return std::list<ePtr<T> >::rend();             
+       }
+
+       iterator eSmartPtrList<T>::erase(iterator it)
+       {
+       //      Remove the item it, if auto-deletion is enabled, than the list call delete for this item
+       //  If current is equal to the item that was removed, current is set to the next item in the list
+               if (autoDelete && *it)
+                       delete *it;                                     
+
+               if (cur == it)
+                       return cur = std::list<ePtr<T> >::erase(it);
+               else
+                       return std::list<ePtr<T> >::erase(it);
+       }
+
+       iterator eSmartPtrList<T>::erase(iterator from, iterator to)
+       {
+       //      Remove all items between the to iterators from and to
+       //      If auto-deletion is enabled, than the list call delete for all removed items
+               while (from != to)
+                       from = erase(from);
+       
+               return from;
+       }
+
+       operator iterator()     
+       {
+       //      Returns a iterator that equal to begin() of the list
+               return begin(); 
+       }
+
+       operator const_iterator() const
+       {
+       //      Returns a const_iterator that equal to begin() of the list
+               return begin(); 
+       }
+
+       operator reverse_iterator()
+       {
+       //      Returns a reverse_iterator that equal to rbegin() of the list
+               return rbegin();        
+       }
+
+       operator const_reverse_iterator() const 
+       {
+       //      Returns a const_reverse_iterator that equal to rbegin() of the list
+               return rbegin();        
+       }
+
+       std::vector<T>* getVector()
+       {
+               // Creates an vector and copys all elements to this vector
+               // returns a pointer to this new vector ( the reserved memory must deletet from the receiver !! )
+               std::vector<T>* v=new std::vector<T>();
+               v->reserve( size() );
+    for ( std_list_T_iterator it( std::list<ePtr<T> >::begin() ); it != std::list<ePtr<T> >::end(); it++)
+                       v->push_back( **it );
+
+               return v;
+       }
+
+       inline iterator insert_in_order( T* e )
+       {
+               // added a new item to the list... in order
+               // returns a iterator to the new item
+               return insert( std::lower_bound( std::list<ePtr<T> >::begin(), std::list<ePtr<T> >::end(), e ), e );
+       }
+
+};
+
+/////////////////// iterator class /////////////////////////////
+template <class T>
+class eSmartPtrList<T>::iterator : public std::list<ePtr<T> >::iterator
+{
+public:
+       // Constructors
+       iterator(const std_list_T_iterator& Q)          : std_list_T_iterator(Q)        {       }
+
+       // changed operator for pointer
+       T* operator->() const
+       {
+               return *std::list<ePtr<T> >::iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+       
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       iterator& operator++()
+       {
+               std::list<ePtr<T> >::iterator::operator++();
+               return *this;
+       }
+
+       iterator operator++(int)
+       {
+               return std::list<ePtr<T> >::iterator::operator++(0);
+       }
+
+       iterator& operator--()
+       {
+               std::list<ePtr<T> >::iterator::operator--();
+               return *this;
+       }
+
+       iterator operator--(int)
+       {
+               return std::list<ePtr<T> >::iterator::operator--(0);
+       }
+};
+
+/////////////////// const_iterator class /////////////////////////////
+template <class T>
+class eSmartPtrList<T>::const_iterator : public std::list<ePtr<T> >::const_iterator
+{
+public:
+       // Constructors
+       const_iterator(const std_list_T_const_iterator& Q)              :std_list_T_const_iterator(Q)   {       }
+
+       // changed operator for pointer
+       T* operator->() const
+       {
+               return *std::list<ePtr<T> >::const_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       const_iterator& operator++()
+       {
+               std::list<ePtr<T> >::const_iterator::operator++();
+               return *this;
+       }
+
+       const_iterator operator++(int)
+       {
+               return std::list<ePtr<T> >::const_iterator::operator++(0);
+       }
+
+       const_iterator& operator--()
+       {
+               std::list<ePtr<T> >::const_iterator::operator--();
+               return *this;
+       }
+
+       const_iterator operator--(int)
+       {
+               return std::list<ePtr<T> >::const_iterator::operator--(0);
+       }
+};
+
+/////////////////// reverse_iterator class /////////////////////////////
+template <class T>
+class eSmartPtrList<T>::reverse_iterator : public std::list<ePtr<T> >::reverse_iterator
+{
+public:
+       // Constructors
+       reverse_iterator(const std_list_T_reverse_iterator& Q)          :std_list_T_reverse_iterator(Q) {       }
+
+       // changed operators for pointer
+       T* operator->() const
+       {
+               return *std::list<ePtr<T> >::reverse_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       reverse_iterator& operator++()
+       {
+               std::list<ePtr<T> >::reverse_iterator::operator++();
+               return *this;
+       }
+
+       reverse_iterator operator++(int)
+       {
+               return std::list<ePtr<T> >::reverse_iterator::operator++(0);
+       }
+
+       reverse_iterator& operator--()
+       {
+               std::list<ePtr<T> >::reverse_iterator::operator--();
+               return *this;
+       }
+
+       reverse_iterator operator--(int)
+       {
+               return std::list<ePtr<T> >::reverse_iterator::operator--(0);
+       }
+};
+
+/////////////////// const_reverse_iterator class /////////////////////////////
+template <class T>
+class eSmartPtrList<T>::const_reverse_iterator : public std::list<ePtr<T> >::const_reverse_iterator
+{
+public:
+       // Constructors
+       const_reverse_iterator(const std_list_T_const_reverse_iterator& Q)              :std_list_T_const_reverse_iterator(Q)   {       }
+
+       // changed operators for pointer
+       T* operator->() const
+       {
+               return *std::list<ePtr<T> >::const_reverse_iterator::operator->();
+       }
+
+       operator T&() const
+       {
+               return *operator->();
+       }
+
+       operator T*() const
+       {
+               return operator->();
+       }
+
+       const_reverse_iterator& operator++()
+       {
+               std::list<ePtr<T> >::const_reverse_iterator::operator++();
+               return *this;
+       }
+
+       const_reverse_iterator operator++(int)
+       {
+               return std::list<ePtr<T> >::const_reverse_iterator::operator++(0);
+       }
+
+       const_reverse_iterator& operator--()
+       {
+               std::list<ePtr<T> >::const_reverse_iterator::operator--();
+               return *this;
+       }
+
+       const_reverse_iterator operator--(int)
+       {
+               return std::list<ePtr<T> >::const_reverse_iterator::operator--(0);
+       }
+};
+
+/////////////////// Default Constructor /////////////////////////////
+template <class T>
+eSmartPtrList<T>::eSmartPtrList()
+    :cur(std::list<ePtr<T> >::begin()), autoDelete(false)              
+{              
+
+}
+
+/////////////////// Copy Constructor /////////////////////////////
+template <class T>
+eSmartPtrList<T>::eSmartPtrList(const eSmartPtrList& e)
+       :std::list<ePtr<T> >(e), cur(e.cur), autoDelete( false )
+{              
+       if ( e.autoDelete )     
+               if ( e.size() )
+                       eDebug("Warning !! We make a Copy of a non empty eSmartPtrList, with autoDelete enabled"
+                                                "We disable autoDelete in the new eSmartPtrList !!");
+               else
+                       autoDelete=true;
+}
+
+/////////////////// eSmartPtrList Destructor /////////////////////////////
+template <class T>
+inline eSmartPtrList<T>::~eSmartPtrList()
+{
+// if autoDelete is enabled, delete is called for all elements in the list
+       if (autoDelete)
+               for (std_list_T_iterator it(std::list<ePtr<T> >::begin()); it != std::list<ePtr<T> >::end(); it++)
+                       delete *it;
+}
+
+
+/////////////////// eSmartPtrList sort() /////////////////////////
+template <class T>
+inline void eSmartPtrList<T>::sort()
+{              
+//     Sorts all items in the list.
+//     The type T must have a operator <.
+       std::list<ePtr<T> >::sort(eSmartPtrList<T>::less());
+}      
+
+/////////////////// eSmartPtrList remove(T*) /////////////////////////
+template <class T>
+inline void eSmartPtrList<T>::remove(T* t)
+{
+//     Remove all items that, equals to t, if auto-deletion is enabled, than the list call delete for the removed items
+//  If current is equal to one of the removed items, current is set to the next valid item
+       T_iterator it(std::list<ePtr<T> >::begin());
+
+       while (it != std::list<ePtr<T> >::end())
+               if (*it == t)
+               {
+                       it=erase(it);
+                       break;  // one item is complete removed an deleted
+               }
+               else
+                       it++;
+       
+       while (it != std::list<ePtr<T> >::end())
+               if (*it == t)
+                       it = std::list<ePtr<T> >::erase(it);  // remove all other items that equals to t (no delete is called..)
+               else
+                       it++;
+                       
+}
+
+/////////////////// eSmartPtrList clear() //////////////////
+template <class T>
+inline void eSmartPtrList<T>::clear()  
+{              
+//     Remove all items from the list
+//     If auto-deletion is enabled, than the list call delete for all items in the list
+       erase(std::list<ePtr<T> >::begin(), std::list<ePtr<T> >::end());        
+}
+
+/////////////////// eSmartPtrList pop_back() ////////////////////
+template <class T>
+inline void eSmartPtrList<T>::pop_back()
+{
+//     Removes the last item from the list. If the current item ist the last, than the current is set to the new
+//     last item in the list;
+//     The removed item is deleted if auto-deletion is enabled.
+       erase(--end());
+}
+
+/////////////////// eSmartPtrList pop_front() ////////////////////
+template <class T>
+inline void eSmartPtrList<T>::pop_front()
+{
+//     Removes the first item from the list. If the current item ist the first, than the current is set to the new
+//     first item in the list;
+//     The removed item is deleted if auto-deletion is enabled.
+       erase(begin());
+}
+
+/////////////////// eSmartPtrList push_back(T*) ////////////////////
+template <class T>
+inline void eSmartPtrList<T>::push_back(T* x)  
+{              
+// Add a new item at the end of the list.
+// The current item is set to the last item;
+       std::list<ePtr<T> >::push_back(x);
+       last(); 
+}
+
+/////////////////// eSmartPtrList push_front(T*) ////////////////////
+template <class T>
+inline void eSmartPtrList<T>::push_front(T* x) 
+{              
+// Add a new item at the begin of the list.
+// The current item is set to the first item;
+       std::list<ePtr<T> >::push_front(x);
+       first();        
+}
+
+/////////////////// eSmartPtrList take() ////////////////////
+//template <class T>
+//inline T* eSmartPtrList<T>::take()
+//{
+//// Takes the current item out of the list without deleting it (even if auto-deletion is enabled).
+//// Returns a pointer to the item taken out of the list, or null if the index is out of range.
+//// The item after the taken item becomes the new current list item if the taken item is not the last item in the list. If the last item is taken, the new last item becomes the current item.
+//// The current item is set to null if the list becomes empty.
+//     T* tmp = *cur;
+//     cur = std::list<T*>::erase(cur);
+//     return tmp;
+//}
+
+/////////////////// eSmartPtrList take(T*) ////////////////////
+//template <class T>
+//inline void eSmartPtrList<T>::take(T* t)
+//{
+//// Takes all item with T* out of the list without deleting it (even if auto-deletion is enabled).
+//     std::list<T*>::remove(t);
+//}
+
+/////////////////// eSmartPtrList setCurrent(T*) ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::setCurrent(const T* t)
+{
+       // Sets the internal current iterator to the first element that equals to t, and returns t when a item is found,
+       // otherwise it returns 0 !
+       for (T_iterator it(std::list<ePtr<T> >::begin()); it != std::list<ePtr<T> >::end(); ++it)
+               if (*it == t)
+               {
+                       cur = it;
+                       return *it;
+               }
+
+       return 0;
+}
+
+/////////////////// eSmartPtrList current() ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::current()
+{
+//     Returns a pointer to the current list item. The current item may be null (implies that the current index is -1).
+       return cur==end() ? 0 : *cur;   
+}
+
+/////////////////// eSmartPtrList next() ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::next()
+{
+//     Returns a pointer to the item succeeding the current item. Returns null if the current items is null or equal to the last item.
+//     Makes the succeeding item current. If the current item before this function call was the last item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == end())
+               return 0;
+       else
+               if (++cur == end())
+                       return 0;
+               else
+                       return *cur;
+}
+
+/////////////////// eSmartPtrList prev() ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::prev()
+{
+//     Returns a pointer to the item preceding the current item. Returns null if the current items is null or equal to the first item.
+//     Makes the preceding item current. If the current item before this function call was the first item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == begin())
+               return 0;
+       else
+               return *--cur;
+}
+
+/////////////////// eSmartPtrList first() ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::first()
+{
+// Returns a pointer to the first item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = begin());        
+}
+
+/////////////////// eSmartPtrList last() ////////////////////
+template <class T>
+inline T* eSmartPtrList<T>::last()
+{
+//     Returns a pointer to the last item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = --end());
+}
+
+/////////////////// const eSmartPtrList current() ////////////////////
+template <class T>
+inline const T* eSmartPtrList<T>::current() const
+{
+//     Returns a pointer to the current list item. The current item may be null (implies that the current index is not valid)
+       return cur==end() ? 0 : *cur;   
+}
+
+/////////////////// const eSmartPtrList next() ////////////////////
+template <class T>
+inline const T* eSmartPtrList<T>::next() const
+{
+//     Returns a pointer to the item succeeding the current item. Returns null if the current items is null or equal to the last item.
+//     Makes the succeeding item current. If the current item before this function call was the last item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == end())
+               return 0;
+       else
+               if (++cur == end())
+                       return 0;
+               else
+                       return *cur;
+}
+
+/////////////////// const eSmartPtrList prev() ////////////////////
+template <class T>
+inline const T* eSmartPtrList<T>::prev() const
+{
+//     Returns a pointer to the item preceding the current item. Returns null if the current items is null or equal to the first item.
+//     Makes the preceding item current. If the current item before this function call was the first item, the current item will be set to null. If the current item was null, this function does nothing.
+       if (cur == begin())
+               return 0;
+       else
+               return *--cur;
+}
+
+/////////////////// const eSmartPtrList first() ////////////////////
+template <class T>
+inline const T* eSmartPtrList<T>::first() const
+{
+// Returns a pointer to the first item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = begin());        
+}
+
+/////////////////// const eSmartPtrList last() ////////////////////
+template <class T>
+inline const T* eSmartPtrList<T>::last() const
+{
+//     Returns a pointer to the last item in the list and makes this the current list item, or null if the list is empty.
+       return *(cur = --end());
+}
+
+////////////////// struct less //////////////////////////////
+template <class T>
+struct eSmartPtrList<T>::less
+{
+//     operator() is used internal from the list to sort them
+       bool operator() (const T* t1, const T* t2)
+       {
+               return (*t1 < *t2);
+       }
+};
+
+/////////////////// eSmartPtrList operator bool ////////////////////
+template <class T>
+eSmartPtrList<T>::operator bool()      
+{
+//     Returns a bool that contains true, when the list is NOT empty otherwise false
+       return !empty();        
+}
+
+template <class T>
+bool eSmartPtrList<T>::operator!()     
+{
+//     Returns a bool that contains true, when the list is empty otherwise false
+       return empty(); 
+}
+
+template <class T>
+void eSmartPtrList<T>::setAutoDelete(bool b)
+{
+//     switched autoDelete on or off
+//     if autoDelete is true, than the pointer list controls the heap memory behind the pointer itself
+//     the list calls delete for the item before it removed from the list
+       autoDelete=b;   
+}
+
+template <class T>
+bool eSmartPtrList<T>::isAutoDelete()
+{
+// returns a bool that contains the state of autoDelete
+       return autoDelete;
+}
+
+#endif // _E_PTRLIST
diff --git a/lib/base/estring.cpp b/lib/base/estring.cpp
new file mode 100644 (file)
index 0000000..bf30d5f
--- /dev/null
@@ -0,0 +1,468 @@
+#include <lib/base/estring.h>
+#include <ctype.h>
+#include <limits.h>
+#include <lib/base/elock.h>
+
+static pthread_mutex_t lock=PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
+
+///////////////////////////////////////// eString sprintf /////////////////////////////////////////////////
+eString& eString::sprintf(char *fmt, ...)
+{
+       singleLock s(lock);
+// Implements the normal sprintf method, to use format strings with eString
+// The max length of the result string is 1024 char.
+       static char buf[1024];
+       va_list ap;
+       va_start(ap, fmt);
+       std::vsnprintf(buf, 1024, fmt, ap);
+       va_end(ap);
+       assign(buf);
+       return *this;
+}
+
+///////////////////////////////////////// eString setNum(uint, uint) ///////////////////////////////////////
+eString& eString::setNum(int val, int sys)
+{
+//     Returns a string that contain the value val as string
+//     if sys == 16 than hexadezimal if sys == 10 than decimal
+       char buf[12];
+
+       if (sys == 10)
+               std::snprintf(buf, 12, "%i", val);
+       else if (sys == 16)
+               std::snprintf(buf, 12, "%X", val);              
+       
+       assign(buf);
+       return *this;
+}
+
+///////////////////////////////////////// eString replaceChars(char, char) /////////////////////////////
+eString& eString::removeChars(char fchar)
+{
+//     Remove all chars that equal to fchar, and returns a reference to itself
+       unsigned int index=0;
+
+       while ( ( index = find(fchar, index) ) != npos )
+               erase(index, 1);
+
+       return *this;
+}
+
+/////////////////////////////////////// eString upper() ////////////////////////////////////////////////
+eString& eString::upper()
+{
+//     convert all lowercase characters to uppercase, and returns a reference to itself
+       for (iterator it = begin(); it != end(); it++)
+               switch(*it)
+               {
+                       case 'a' ... 'z' :
+                               *it -= 32;
+                       break;
+
+                       case 'ä' :
+                               *it = 'Ä';
+                       break;
+                       
+                       case 'ü' :
+                               *it = 'Ü';
+                       break;
+                       
+                       case 'ö' :
+                               *it = 'Ö';
+                       break;
+               }
+
+       return *this;
+}
+
+eString& eString::strReplace(const char* fstr, const eString& rstr)
+{
+//     replace all occurrence of fstr with rstr and, and returns a reference to itself
+       unsigned int index=0;
+       unsigned int fstrlen = strlen(fstr);
+       int rstrlen=rstr.size();
+
+       while ( ( index = find(fstr, index) ) != npos )
+       {
+               replace(index, fstrlen, rstr);
+               index+=rstrlen;
+       }
+       
+       return *this;
+}
+
+int strnicmp(const char *s1, const char *s2, int len)
+{
+//     makes a case insensitive string compare with len Chars
+       while ( *s1 && *s2 && len-- )
+               if ( tolower(*s1) != tolower(*s2) )
+                       return tolower(*s1) < tolower(*s2) ? -1 : 1;
+               else
+                       s1++, s2++;
+
+       return 0;
+}
+
+/////////////////////////////////////// eString icompare(const eString&) ////////////////////////////////////////////////
+int eString::icompare(const eString& s)
+{
+//     makes a case insensitive string compare
+       std::string::const_iterator p = begin(),
+                                                                                                                       p2 = s.begin();
+
+       while ( p != end() && p2 != s.end() )
+               if ( tolower(*p) != tolower(*p2) )
+                       return tolower(*p) < tolower(*p2) ? -1 : 1;
+               else
+                       p++, p2++;
+
+       return length() == s.length() ? 0 : length() < s.length() ? -1 : 1;
+}
+
+               // 8859-x to dvb coding tables. taken from www.unicode.org/Public/MAPPINGS/ISO8859/
+static unsigned long c88595[128]={
+0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, 
+0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 
+0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 
+0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 
+0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 
+0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f};
+
+static unsigned long c88596[128]={
+0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000, 
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, 
+0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 
+0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 
+0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
+
+static unsigned long c88597[128]={
+0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+0x00a0, 0x2018, 0x2019, 0x00a3, 0x0000, 0x0000, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015, 
+0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, 
+0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 
+0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 
+0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 
+0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000};
+
+static unsigned long c88598[128]={
+0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
+0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000, 
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, 
+0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 
+0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000};
+
+static unsigned long c88599[128]={
+0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 
+0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 
+0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 
+0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 
+0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 
+0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, 
+0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 
+0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff};
+
+               // UPC Direct / HBO strange two-character encoding. 0xC2 means acute, 0xC8 doule 'dot', 0xCA small 'circle', 0xCD double 'acute', 0xCF acute.
+               // many thanks to the czechs who helped me while solving this.
+static inline unsigned int doCzech(int c1, int c2)
+{
+       switch (c1)
+       {
+       case 0xC2: // acute
+               switch (c2)
+               {
+               case 'A': return 0x00C1;
+               case 'a': return 0x00E1;
+               case 'E': return 0x00C9;
+               case 'e': return 0x00E9;
+               case 'I': return 0x00CD;
+               case 'i': return 0x00ED;
+               case 'O': return 0x00D3;
+               case 'o': return 0x00F3; // corrected, was 0x00E3
+               case 'U': return 0x00DA;
+               case 'u': return 0x00FA;
+               case 'Y': return 0x00DD;
+               case 'y': return 0x00FD;
+               default:
+                       return 0;
+               }
+       case 0xC8: // double 'dot'
+               switch (c2)
+               {
+               case 'A': return 0x00C4;
+               case 'a': return 0x00E4;
+               case 'E': return 0x00CB;
+               case 'e': return 0x00EB;
+               case 'O': return 0x00D6;
+               case 'o': return 0x00F6;
+               case 'U': return 0x00DC;
+               case 'u': return 0x00FC;
+               default:
+                       return 0;
+               }
+       case 0xCA: // small 'circle'
+               switch (c2)               
+               {                         
+               case 'U': return 0x016E;  
+               case 'u': return 0x016F;  
+               default:                  
+                       return 0;             
+               }                         
+       case 0xCD: // double 'acute'
+               switch (c2)               
+               {                         
+               case 'O': return 0x0150;  
+               case 'o': return 0x0151;  
+               case 'U': return 0x0170;  
+               case 'u': return 0x0171;  
+               default:                  
+                       return 0;             
+               }                         
+       case 0xCF: // caron
+               switch (c2)
+               {
+               case 'C': return 0x010C;
+               case 'c': return 0x010D;
+               case 'D': return 0x010E;
+               case 'd': return 0x010F;
+               case 'E': return 0x011A;
+               case 'e': return 0x011B;
+               case 'L': return 0x013D;        // not sure if they really exist.
+               case 'l': return 0x013E;
+               case 'N': return 0x0147;
+               case 'n': return 0x0148;
+               case 'R': return 0x0158;
+               case 'r': return 0x0159;
+               case 'S': return 0x0160;
+               case 's': return 0x0161;
+               case 'T': return 0x0164;
+               case 't': return 0x0165;
+               case 'Z': return 0x017D;
+               case 'z': return 0x017E;
+               default:
+                       return 0;
+               }
+       default:
+               return 0;
+       }
+}
+
+static inline unsigned int recode(unsigned char d, int cp)
+{
+       if (d < 0x80)
+               return d;
+       switch (cp)
+       {
+       case 0:         // 8859-1 Latin1 <-> unicode mapping
+               return d;
+       case 1:         // 8859-5 -> unicode mapping
+               return c88595[d-0x80];
+       case 2:         // 8859-6 -> unicode mapping
+               return c88596[d-0x80];
+       case 3:         // 8859-7 -> unicode mapping
+               return c88597[d-0x80];
+       case 4:         // 8859-8 -> unicode mapping
+               return c88598[d-0x80];
+       case 5:         // 8859-9 -> unicode mapping
+               return c88599[d-0x80];
+       default:
+               return d;
+       }
+}
+
+eString convertDVBUTF8(unsigned char *data, int len, int table)
+{
+       int i;
+       if (!len)
+               return "";
+               
+       i=0;
+       if (data[0] <= 5)
+               table=data[i++];
+       if ((data[0] >= 0x10) && (data[0] <= 0x12))
+               return "<unsupported encoding>";
+
+       int bytesneeded=0, t=0, s=i;
+       
+       for (; i<len; ++i)
+       {
+               unsigned long code=0;
+               if ((table == 5) && ((data[i] == 0xC2) || (data[i] == 0xC8) || (data[i] == 0xCA) || (data[i] == 0xCD) || (data[i] == 0xCF)) && (i+1 < len))
+                               // braindead czech encoding...
+                       if ((code=doCzech(data[i], data[i+1])))
+                               ++i;
+               if (!code)
+                       code=recode(data[i], table);
+               if (!code)
+                       continue;
+               if (code >= 0x10000)
+                       bytesneeded++;
+               if (code >= 0x800)
+                       bytesneeded++;
+               if (code >= 0x80)
+                       bytesneeded++;
+               bytesneeded++;
+       }
+       
+       i=s;
+       
+       unsigned char res[bytesneeded];
+       
+       while (i < len)
+       {
+               unsigned long code=0;
+               if ((table == 5) && ((data[i] == 0xC2) || (data[i] == 0xC8) || (data[i] == 0xCA) || (data[i] == 0xCD) || (data[i] == 0xCF)) && (i+1 < len))
+                               // braindead czech encoding...
+                       if ((code=doCzech(data[i], data[i+1])))
+                               i+=2;
+               if (!code)
+                       code=recode(data[i++], table);
+               if (!code)
+                       continue;
+                               // Unicode->UTF8 encoding
+               if (code < 0x80) // identity ascii <-> utf8 mapping
+                       res[t++]=char(code);
+               else if (code < 0x800) // two byte mapping
+               {
+                       res[t++]=(code>>6)|0xC0;
+                       res[t++]=(code&0x3F)|0x80;
+               } else if (code < 0x10000) // three bytes mapping
+               {
+                       res[t++]=(code>>12)|0xE0;
+                       res[t++]=((code>>6)&0x3F)|0x80;
+                       res[t++]=(code&0x3F)|0x80;
+               } else
+               {
+                       res[t++]=(code>>18)|0xF0;
+                       res[t++]=((code>>12)&0x3F)|0x80;
+                       res[t++]=((code>>6)&0x3F)|0x80;
+                       res[t++]=(code&0x3F)|0x80;
+               }
+       }
+       if ( t != bytesneeded)
+               eFatal("t: %d, bytesneeded: %d", t, bytesneeded);
+       return eString().assign((char*)res, t);
+}
+
+eString convertUTF8DVB(const eString &string)
+{
+       eString ss=eString();
+       
+       int len=string.length();
+       for(int i=0;i<len;i++){
+               unsigned char c1=string[i];
+               unsigned int c;
+               if(c1<0x80)
+                       c=c1;
+               else{
+                       i++;
+                       unsigned char c2=string[i];
+                       c=((c1&0x3F)<<6) + (c2&0x3F);
+               }
+               // c = UNICODE
+               // now search it in table
+               if(c>=0x80){
+                       for(unsigned int j=0;j<128;j++){
+                               if(c88599[j]==c){            // now only 8859-9 ....
+                                       c=0x80+j;
+                                       break;
+                               }
+                       }
+               }
+               ss+=c;
+       }
+
+       return ss;
+}
+
+eString convertLatin1UTF8(const eString &string)
+{
+       unsigned int bytesneeded=0, t=0, i;
+       
+       unsigned int len=string.size();
+       
+       for (i=0; i<len; ++i)
+       {
+               unsigned long code=string[i];
+               if (!code)
+                       continue;
+               if (code >= 0x10000)
+                       bytesneeded++;
+               if (code >= 0x800)
+                       bytesneeded++;
+               if (code >= 0x80)
+                       bytesneeded++;
+               bytesneeded++;
+       }
+       
+       i=0;
+       
+       unsigned char res[bytesneeded];
+       
+       while (i < len)
+       {
+               unsigned long code=string[i++];
+                               // Unicode->UTF8 encoding
+               if (code < 0x80) // identity latin <-> utf8 mapping
+                       res[t++]=char(code);
+               else if (code < 0x800) // two byte mapping
+               {
+                       res[t++]=(code>>6)|0xC0;
+                       res[t++]=(code&0x3F)|0x80;
+               } else if (code < 0x10000) // three bytes mapping
+               {
+                       res[t++]=(code>>12)|0xE0;
+                       res[t++]=((code>>6)&0x3F)|0x80;
+                       res[t++]=(code&0x3F)|0x80;
+               } else
+               {
+                       res[t++]=(code>>18)|0xF0;
+                       res[t++]=((code>>12)&0x3F)|0x80;
+                       res[t++]=((code>>6)&0x3F)|0x80;
+                       res[t++]=(code&0x3F)|0x80;
+               }
+       }
+       if ( t != bytesneeded)
+               eFatal("t: %d, bytesneeded: %d", t, bytesneeded);
+       return eString().assign((char*)res, t);
+}
+
+int isUTF8(const eString &string)
+{
+       unsigned int len=string.size();
+       
+       for (unsigned int i=0; i < len; ++i)
+       {
+               if (!(string[i]&0x80)) // normal ASCII
+                       continue;
+               if ((string[i] & 0xE0) == 0xC0) // one char following.
+               {
+                               // first, length check:
+                       if (i+1 >= len)
+                               return 0; // certainly NOT utf-8
+                       i++;
+                       if ((string[i]&0xC0) != 0x80)
+                               return 0; // no, not UTF-8.
+               } else if ((string[i] & 0xF0) == 0xE0)
+               {
+                       if ((i+1) >= len)
+                               return 0;
+                       i++;
+                       if ((string[i]&0xC0) != 0x80)
+                               return 0;
+                       i++;
+                       if ((string[i]&0xC0) != 0x80)
+                               return 0;
+               }
+       }
+       return 1; // can be UTF8 (or pure ASCII, at least no non-UTF-8 8bit characters)
+}
+
diff --git a/lib/base/estring.h b/lib/base/estring.h
new file mode 100644 (file)
index 0000000..36f6636
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef __E_STRING__
+#define __E_STRING__
+
+#include <string>
+#include <stdarg.h>
+#include <stdio.h>
+#include "eerror.h"
+
+int strnicmp(const char*, const char*, int);
+
+class eString : public std::string
+{
+public:
+// constructors
+       inline eString()        {}      
+       inline eString(const char* p);
+       inline eString(const char* p, int cnt);
+       inline eString(const std::string &s);
+// methods
+       inline eString left(unsigned int len) const;
+       inline eString mid(unsigned int index, unsigned int len=(unsigned)-1) const;
+       inline eString right(unsigned int len) const;
+       bool isNull() const;
+// operators
+       inline operator bool() const;
+       inline bool operator!() const;
+// methods with implementation in estring.cpp
+       eString& sprintf(char *fmt, ...);
+       eString& setNum(int val, int sys=10);
+       eString& removeChars(const char fchar);
+       eString& strReplace(const char* fstr, const eString& rstr);
+       eString& upper();
+       int icompare(const eString& s);
+};
+
+eString convertDVBUTF8(unsigned char *data, int len, int table=5);
+eString convertUTF8DVB(const eString &string);  // with default ISO8859-5
+eString convertLatin1UTF8(const eString &string);
+int isUTF8(const eString &string);
+
+/////////////////////////////////////////////// Copy Constructors ////////////////////////////////////////////////
+inline eString::eString(const std::string &s)
+       :std::string(s)
+{
+}
+
+inline eString::eString(const char* p)
+       :std::string(p?p:"")     // when the char* p is null, than use ""... otherwise crash...
+{
+}
+
+inline eString::eString(const char* p, int cnt)
+       :std::string(p, cnt)
+{
+}
+
+///////////////////////////////////////// eString operator bool /////////////////////////////////////////////////
+inline eString::operator bool() const
+{
+// Returns a bool that contains true if the string longer than 0 Character otherwise false;
+       return !empty();
+}
+
+///////////////////////////////////////// eString operator! ////////////////////////////////////////////////////
+inline bool eString::operator!() const
+{
+// Returns a bool that contains true if the string ist empty otherwise false;
+       return empty();
+}
+
+///////////////////////////////////////// eString left //////////////////////////////////////////////////////////
+inline eString eString::left(unsigned int len) const
+{
+//     Returns a substring that contains the len leftmost characters of the string.
+//     The whole string is returned if len exceeds the length of the string.
+       return len >= length() ? *this : substr(0, len);
+}
+
+//////////////////////////////////////// eString mid ////////////////////////////////////////////////////////////
+inline eString eString::mid(unsigned int index, unsigned int len) const
+{
+//     Returns a substring that contains the len characters of this string, starting at position index.
+//     Returns a null string if the string is empty or index is out of range. Returns the whole string from index if index+len exceeds the length of the string.
+       register unsigned int strlen = length();
+
+       if (index >= strlen)
+               return eString();
+
+       if (len == (unsigned)-1)
+               return substr(index);
+
+       if (strlen < index + len)
+               len = strlen-index;
+
+       return substr(index, len);
+}
+
+//////////////////////////////////////// eString right ////////////////////////////////////////////////////////////
+inline eString eString::right(unsigned int len) const
+{
+//     Returns a substring that contains the len rightmost characters of the string.
+//     The whole string is returned if len exceeds the length of the string.
+       register unsigned int strlen = length();
+       return len >= strlen ? *this : substr(strlen-len, len);
+}
+
+inline bool eString::isNull() const
+{
+//     Returns a bool, that contains true, when the internal char* is null (only when a string ist empty constructed)
+       return !c_str();
+}
+
+#endif // __E_STRING__
diff --git a/lib/base/i18n.h b/lib/base/i18n.h
new file mode 100644 (file)
index 0000000..96d5402
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * i18n.h: gettext defines and includes
+ *
+ * Copyright (C) 2002 Bastian Blank <waldi@tuxbox.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: i18n.h,v 1.1 2003-10-17 15:35:47 tmbinc Exp $
+ */
+
+#ifndef __CORE__BASE__I18N_H
+#define __CORE__BASE__I18N_H
+
+#include <libintl.h>
+#define _(string) gettext (string)
+
+#endif
diff --git a/lib/base/init.cpp b/lib/base/init.cpp
new file mode 100644 (file)
index 0000000..b9cf1de
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <lib/base/init.h>
+#include <lib/base/eerror.h>
+
+int eInit::rl=-1;
+std::list<std::pair<int,eAutoInit*> > *eInit::cl;
+
+void eInit::add(int trl, eAutoInit *c)
+{
+       if (!cl)
+               cl=new std::list<std::pair<int,eAutoInit*> >;
+       cl->push_back(std::pair<int,eAutoInit*>(trl, c));
+       if (rl>=trl)
+               c->initNow();
+}
+
+void eInit::remove(int trl, eAutoInit *c)
+{
+       if (!cl)
+               return;
+       cl->remove(std::pair<int,eAutoInit*>(trl, c));
+       if (rl>=trl)
+               c->closeNow();
+}
+
+eInit::eInit()
+{
+}
+
+eInit::~eInit()
+{
+       setRunlevel(-1);
+       delete cl;
+       cl=0;
+}
+
+void eInit::setRunlevel(int nrl)
+{
+       while (nrl>rl)
+       {
+               rl++;
+                       
+               for (std::list<std::pair<int,eAutoInit*> >::iterator i(cl->begin()); i!=cl->end(); ++i)
+               {
+                       if ((*i).first == rl)
+                       {
+                               eDebug("+ (%d) %s", rl, (*i).second->getDescription());
+                               (*i).second->initNow();
+                       }
+               }
+       }
+       
+       while (nrl<rl)
+       {
+               for (std::list<std::pair<int,eAutoInit*> >::iterator i(cl->begin()); i!=cl->end(); ++i)
+                       if ((*i).first == rl)
+                       {
+                               eDebug("- (%d) %s", rl, (*i).second->getDescription());
+                               (*i).second->closeNow();
+                       }
+               rl--;
+       }
+       eDebug("reached rl %d", rl);
+}
+
+eAutoInit::~eAutoInit()
+{
+}
diff --git a/lib/base/init.h b/lib/base/init.h
new file mode 100644 (file)
index 0000000..465bac4
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef __init_h
+#define __init_h
+
+#include <list>
+#include <utility>
+
+class eAutoInit;
+
+class eInit
+{
+       static std::list<std::pair<int,eAutoInit*> > *cl;
+       friend class eAutoInit;
+       static int rl;
+public:
+       eInit();
+       ~eInit();
+       static void setRunlevel(int rlev);
+       static void add(int trl, eAutoInit *c);
+       static void remove(int trl, eAutoInit *c);
+};
+
+class eAutoInit
+{
+       friend class eInit;
+       virtual void initNow()=0;
+       virtual void closeNow()=0;
+protected:
+       int rl;
+       char *description;
+public:
+       eAutoInit(int rl, char *description): rl(rl), description(description)
+       {
+       }
+       virtual ~eAutoInit();
+       const char *getDescription() const { return description; };
+};
+
+template<class T1, class T2> class
+eAutoInitP1: protected eAutoInit
+{
+       T1 *t;
+       const T2 &arg;
+       void initNow()
+       {
+               t=new T1(arg);
+       }
+       void closeNow()
+       {
+               delete t;
+       }
+public:
+       operator T1*()
+       {
+               return t;
+       }
+       eAutoInitP1(const T2 &arg, int runl, char *description): eAutoInit(runl, description), arg(arg)
+       {
+               eInit::add(rl, this);
+       }
+       ~eAutoInitP1()
+       {
+               eInit::remove(rl, this);
+       }
+};
+
+template<class T1> class
+eAutoInitP0: protected eAutoInit
+{
+       T1 *t;
+       void initNow()
+       {
+               t=new T1();
+       }
+       void closeNow()
+       {
+               delete t;
+       }
+public:
+       operator T1*()
+       {
+               return t;
+       }
+       T1 *operator->()
+       {
+               return t;
+       }
+       eAutoInitP0(int runl, char *description): eAutoInit(runl, description)
+       {
+               eInit::add(rl, this);
+       }
+       ~eAutoInitP0()
+       {
+               eInit::remove(rl, this);
+       }
+};
+
+#endif
diff --git a/lib/base/init_num.h b/lib/base/init_num.h
new file mode 100644 (file)
index 0000000..a9da062
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __lib_system_init_num_
+#define __lib_system_init_num_
+
+namespace eAutoInitNumbers
+{
+       enum { increment=5 };
+       enum
+       {
+               configuration=0,
+               lowlevel=configuration+increment,
+               graphic=lowlevel+increment,
+               skin=graphic+increment,
+               rc=skin+increment,
+               guiobject=rc+increment,
+               actions=guiobject+increment,
+               dvb=actions+increment,
+               service=dvb+increment,
+               osd=service+increment,
+               wizard=osd+increment,
+               main=osd+increment*5,
+       };
+};
+
+#endif
diff --git a/lib/base/message.cpp b/lib/base/message.cpp
new file mode 100644 (file)
index 0000000..dafbf3f
--- /dev/null
@@ -0,0 +1,49 @@
+#include <lib/base/message.h>
+#include <unistd.h>
+#include <lib/base/eerror.h>
+
+eMessagePump::eMessagePump(int mt): content(1024*1024), ismt(mt)
+{
+       pipe(fd);
+}
+
+eMessagePump::~eMessagePump()
+{      
+       if (ismt)
+               content.lock(); // blocks until all messages are processed.
+       close(fd[0]);
+       close(fd[1]);
+}
+
+int eMessagePump::send(const void *data, int len)
+{
+       if (ismt)
+               content.lock(len);
+       return ::write(fd[1], data, len)<0;
+}
+
+int eMessagePump::recv(void *data, int len)
+{
+       unsigned char*dst=(unsigned char*)data;
+       while (len)
+       {
+               if (ismt)
+                       content.unlock(len);
+               int r=::read(fd[0], dst, len);
+               if (r<0)
+                       return r;
+               dst+=r;
+               len-=r;
+       }
+       return 0;
+}
+
+int eMessagePump::getInputFD() const
+{
+       return fd[1];
+}
+
+int eMessagePump::getOutputFD() const
+{
+       return fd[0];
+}
diff --git a/lib/base/message.h b/lib/base/message.h
new file mode 100644 (file)
index 0000000..6a9ff43
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef __lib_base_message_h
+#define __lib_base_message_h
+
+#include <lib/base/ebase.h>
+#include <unistd.h>
+#include <lib/base/elock.h>
+
+/**
+ * \brief A generic messagepump.
+ *
+ * You can send and receive messages with this class. Internally a fifo is used,
+ * so you can use them together with a \c eMainloop.
+ */
+class eMessagePump
+{
+       int fd[2];
+       eLock content;
+       int ismt;
+public:
+       eMessagePump(int mt=0);
+       ~eMessagePump();
+       int send(const void *data, int len);
+       int recv(void *data, int len); // blockierend
+       int getInputFD() const;
+       int getOutputFD() const;
+};
+
+/**
+ * \brief A messagepump with fixed-length packets.
+ *
+ * Based on \ref eMessagePump, with this class you can send and receive fixed size messages.
+ * Automatically creates a eSocketNotifier and gives you a callback.
+ */
+template<class T>
+class eFixedMessagePump: private eMessagePump, public Object
+{
+       eSocketNotifier *sn;
+       void do_recv(int)
+       {
+               T msg;
+               recv(&msg, sizeof(msg));
+               /*emit*/ recv_msg(msg);
+       }
+public:
+       Signal1<void,const T&> recv_msg;
+       void send(const T &msg)
+       {
+               eMessagePump::send(&msg, sizeof(msg));
+       }
+       eFixedMessagePump(eMainloop *context, int mt): eMessagePump(mt)
+       {
+               sn=new eSocketNotifier(context, getOutputFD(), eSocketNotifier::Read);
+               CONNECT(sn->activated, eFixedMessagePump<T>::do_recv);
+               sn->start();
+       }
+       ~eFixedMessagePump()
+       {
+               delete sn;
+       }
+       void start() { sn->start(); }
+       void stop() { sn->stop(); }
+};
+
+#endif
diff --git a/lib/base/nconfig.cpp b/lib/base/nconfig.cpp
new file mode 100644 (file)
index 0000000..a0e4a31
--- /dev/null
@@ -0,0 +1,1027 @@
+// this is nconfig 0.92, a bit modified
+#define NO_MAP_SHARED
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <lib/base/nconfig.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <memory.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sched.h>
+
+#include <sys/mman.h>
+
+#include <limits.h>
+
+#ifndef PAGESIZE
+#ifdef PAGE_SIZE
+#define PAGESIZE PAGE_SIZE
+#else
+#define PAGESIZE 4096
+#endif
+#endif
+
+#define SB                             ((struct nc_sb_s *) data)
+#define CM(x)                  ((struct nc_chunk_s *) (data+(x)))
+#define DE(x)                  ((struct nc_de_s *) (data+(x)))
+#define IDE(x, y)              (DE(((unsigned *) (data+(x)->offset))[(y)]))
+#define CS(x)                  (((unsigned *) (data+(x)))[-1])
+
+inline unsigned NConfig::crc(const char *d, unsigned len)
+{
+       unsigned ret = 0;
+       unsigned l = len / sizeof(unsigned);
+
+       while (l) {
+               ret += *(const unsigned *)d;
+               ret = (ret << 3) & (ret >> 29);
+               l--;
+               d += sizeof(unsigned);
+       }
+       return ret;
+}
+
+NConfig::NConfig(int protect)
+{
+       fd = -1;
+       cname = fname = data = NULL;
+       sb = NULL;
+       cdir = NULL;
+       chunks = NULL;
+       revision = update = lsize = omode = 0;
+       olck = 0;
+       lock = NC_L_NONE;
+       careful = protect;
+}
+
+NConfig::~NConfig()
+{
+       close();
+       free(fname);
+}
+
+void NConfig::close()
+{
+       free(cname);
+       cname = NULL;
+       if (fd > -1) {
+#ifdef NO_MAP_SHARED
+               if (data) {
+                       int size=sb->size;
+                       char *buffer=new char[size];
+                       memcpy(buffer, data, size);
+                       munmap(data, size);
+                       data = NULL;
+                       ::lseek(fd, 0, SEEK_SET);
+                       ::write(fd, buffer, size);
+                       delete[] buffer;
+               }
+#endif
+               ::close(fd);
+               fd = -1;
+       }
+       if (data) {
+               munmap(data, sb->size);
+               data = NULL;
+       }
+}
+
+void NConfig::flush()
+{
+       close();
+       open(omode);
+}
+
+int NConfig::setName(const char *name)
+{
+       if (!name)
+               return NC_ERR_NVAL;
+       if (fd > -1)
+               return NC_ERR_PERM;
+       free(fname);
+       fname = strdup(name);
+       return NC_ERR_OK;
+}
+
+int NConfig::createNew(unsigned resize, unsigned dirent, unsigned mchunks)
+{
+       if (fd > -1)
+               return NC_ERR_NVAL;
+       if (!access(fname, F_OK))
+               return NC_ERR_PERM;
+
+       int ff;
+       if ((ff = ::open(fname, O_WRONLY | O_CREAT, 0600)) == -1)
+               return NC_ERR_NFILE;
+       struct nc_sb_s bsb = {NC_SB_MAGIC, resize*PAGESIZE, 
+                                               dirent, mchunks, resize, mchunks,
+                                               sizeof(struct nc_sb_s)+sizeof(struct nc_de_s)+2*sizeof(unsigned),
+                                               sizeof(struct nc_sb_s), 0};
+       struct nc_de_s bde = {sizeof(struct nc_sb_s)+sizeof(struct nc_de_s),
+                                               NC_DIR, sizeof(struct nc_sb_s), 0, 0, 0};
+       struct nc_chunk_s bcm;
+
+       write(ff, &bsb, sizeof(bsb));
+       write(ff, &bde, sizeof(bde));
+       write(ff, "/", 2);
+
+       lseek(ff, sizeof(unsigned)-2, SEEK_CUR);
+       unsigned cl = sizeof(nc_chunk_s)*mchunks+sizeof(unsigned);
+       write(ff, &cl, sizeof(unsigned));
+
+       bcm.offset = bsb.chunk + sizeof(struct nc_chunk_s)*mchunks;
+       bcm.size = bsb.size - bcm.offset;
+
+       write(ff, &bcm, sizeof(bcm));
+
+       lseek(ff, bsb.size-1, SEEK_SET);
+       write(ff, "", 1);
+       ::close(ff);
+       return NC_ERR_OK;
+}
+       
+
+int NConfig::open(int how)
+{
+       if (!fname)
+               return NC_ERR_NFILE;
+       if (how != NC_O_RO && how != NC_O_RW)
+               return NC_ERR_TYPE;
+       if (fd > -1)
+               close();
+
+       int ff;
+       if ((ff = ::open(fname, how)) == -1)
+               return NC_ERR_PERM;
+
+       struct stat sbuf;
+       fstat(ff, &sbuf);
+
+       if (!sbuf.st_size)
+               return NC_ERR_CORRUPT;
+
+#ifdef NO_MAP_SHARED
+       if ((data = (char *) mmap(NULL, sbuf.st_size, how == NC_O_RO ? PROT_READ : (PROT_READ|PROT_WRITE), MAP_PRIVATE, ff, 0)) == MAP_FAILED) {
+#else
+       if ((data = (char *) mmap(NULL, sbuf.st_size, how == NC_O_RO ? PROT_READ : (PROT_READ|PROT_WRITE), MAP_SHARED, ff, 0)) == MAP_FAILED) {
+#endif
+               ::close(ff);
+               return NC_ERR_NMEM;
+       }
+       if (memcmp(((struct nc_sb_s *) data)->magic, NC_SB_MAGIC, 4)) {
+               munmap(data, sbuf.st_size);
+               ::close(ff);
+               return NC_ERR_CORRUPT;
+       }
+       fd = ff;
+       omode = how;
+       sb = SB;
+       lsize = 0;
+       cname = strdup("/");
+
+       lockFile(NC_L_RO, TRUE);
+       rdir = DE(sb->root);
+       unLockFile();
+       return NC_ERR_OK;
+}
+
+void NConfig::expand(unsigned toadd)
+{
+       unsigned nsize = sb->size + toadd;
+       lseek(fd, nsize-1, SEEK_SET);
+       write(fd, "", 1);
+       _remap(sb->size, nsize);
+       sb->size = nsize;
+       cdir = getDirEnt(cname);
+       chunks = CM(sb->chunk);
+#ifdef NC_DEBUG_ALLOC
+       fprintf(stderr, "Expanded from %u to %u\n", nsize-toadd, nsize);
+#endif
+}
+
+unsigned NConfig::getChunk(unsigned s)
+{
+       int lst = -1;
+
+       // Make sure we get aligned data
+       s = alignSize(s) + sizeof(unsigned);
+
+#ifdef NC_DEBUG_ALLOC
+       fprintf(stderr, "Taking %u (total %u)\n", s, sb->chunk_ttl);
+#endif
+
+       do {
+               int left = 0, right = sb->chunk_ttl - 1, c;
+               while (left <= right) {
+                       int diff = chunks[c = (left + right) / 2].size - s;
+                       if (diff < 0 || diff == sizeof(unsigned)) {
+#ifdef NC_DEBUG_ALLOC
+                               if (diff > 0)
+                                       fprintf(stderr, "Rejected chunk %d (%u:%u)\n", c, chunks[c].offset, chunks[c].size);
+#endif
+                               right = c - 1;
+                               continue;
+                       }
+                       lst = c;
+                       if (!diff)
+                               break;
+                       left = c + 1;
+               }
+               if (lst < 0) {
+                       unsigned ll = (s / (sb->size_inc*PAGESIZE) + 1) * PAGESIZE * sb->size_inc;
+                       // we don't have a suitable chunk
+                       expand(ll);
+                       // insert new chunk into list (always succeeds)
+                       *(unsigned *)(data+sb->size-ll) = ll;
+                       fast_free(sb->size-ll+sizeof(unsigned));
+               }
+       } while (lst < 0);
+
+#ifdef NC_DEBUG_ALLOC
+       fprintf(stderr, "haluz 7: off = %u size = %u\n", chunks[7].offset, chunks[7].size);
+       fprintf(stderr, "Got %u chunk (pos %d), taking %u\n", chunks[lst].size, lst, s);
+       fprintf(stderr, "chunk (%u:%u)\n", chunks[lst].offset, chunks[lst].size); 
+#endif
+
+       unsigned best = chunks[lst].offset+sizeof(unsigned);
+       memset(data+best, 0, s-sizeof(unsigned));
+       chunks[lst].size -= s;
+       chunks[lst].offset += s;
+       CS(best) = s;
+
+       while (lst < ((signed)sb->chunk_ttl - 1) && chunks[lst].size < chunks[lst+1].size) {
+               unsigned b = chunks[lst].size;
+               unsigned i = lst + 1;
+               chunks[lst].size = chunks[i].size;
+               chunks[i].size = b;
+               b = chunks[lst].offset;
+               chunks[lst].offset = chunks[i].offset;
+               chunks[i].offset = b;
+               lst = i;
+       }
+
+#ifdef NC_DEBUG_ALLOC
+       fprintf(stderr, "Returned %u:%u\n", best, CS(best));
+#endif
+       return best;
+}
+
+void NConfig::freeChunk(unsigned where)
+{
+#ifdef NC_DEBUG_ALLOC
+       fprintf(stderr, "Free chunk: %u\n", CS(where));
+#endif
+       if (chunks[sb->chunk_ttl-2].size) {
+#ifdef NC_DEBUG_ALLOC
+               fprintf(stderr, "Last slot available.\n");
+#endif
+               unsigned n = getChunk((sb->chunk_ttl+sb->chunk_inc)*sizeof(struct nc_chunk_s));
+               unsigned f = sb->chunk;
+               memcpy(data+n, chunks, (sb->chunk_ttl-1)*sizeof(struct nc_chunk_s));
+               chunks = CM(sb->chunk = n);
+               sb->chunk_ttl += sb->chunk_inc;
+               fast_free(f);
+       }
+       fast_free(where);
+}
+
+inline unsigned NConfig::alignSize(unsigned s)
+{
+       unsigned of = s % sizeof(unsigned);
+       return of ? s + sizeof(unsigned) - of : s;
+}
+
+void NConfig::delKey(const char *name)
+{
+       _delKey(name, NULL, TRUE);
+}
+
+void NConfig::_delKey(const char *name, struct nc_de_s *p, int tosort)
+{
+       if (fd < 0)
+               return;
+       lockFile(NC_L_RW);
+       struct nc_de_s *nd = getDirEnt(name, p);
+       if (nd && nd != rdir && nd != cdir) {
+               unsigned ndo = ((char *)nd) - data;
+               if (nd->type == NC_DIR)
+                       for (unsigned i=0; i<DE(ndo)->pages; i++) {
+                               struct nc_de_s *dd = IDE(nd, i);
+                               if (dd->type)
+                                       _delKey(data+dd->name, nd, FALSE);
+                               nd = DE(ndo);
+                       }
+               sb->modtime++;
+               freeChunk(nd->offset);
+               freeChunk(DE(ndo)->name);
+               nd = DE(ndo);
+               struct nc_de_s *parent = DE(nd->parent);
+               memset(nd, 0, sizeof(struct nc_de_s));
+               // keep parent directory sorted
+               if (tosort) {
+                       unsigned i = 0;
+                       while (i < parent->pages && IDE(parent, i) != nd)
+                                i++;
+                       memmove(((unsigned *)(data+parent->offset))+i,
+                               ((unsigned *)(data+parent->offset))+i+1,
+                               sizeof(unsigned)*(parent->pages-i-1));
+                       ((unsigned *)(data+parent->offset))[parent->pages-1] = ndo;
+               }
+       }
+       unLockFile();
+}
+
+int NConfig::_setKey(const char *name, const unsigned t, const char *value, const unsigned len)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       if (omode != NC_O_RW)
+               return NC_ERR_RDONLY;
+       lockFile(NC_L_RW);
+       struct nc_de_s *nd = getDirEnt(name);
+#ifdef NC_DEBUG_INSERT
+       fprintf(stderr, "Found DE %p\n", nd);
+#endif
+       if (!nd) {
+               struct nc_de_s *sd = *name == '/' ? rdir : cdir;
+               char *parse = canonize(name), *p = parse;
+       
+               while ((nd = getDirEnt(p, sd)))
+                       if (nd->type == NC_DIR) {
+                               sd = nd;
+                               p += strlen(p)+1;
+                       } else {
+                               free(parse);
+                               unLockFile();
+                               return NC_ERR_PERM;
+                       }
+
+               size_t pl = 0;
+               struct nc_de_s ds;
+               unsigned sdo = ((char *)sd) - data;
+               while (*(p+(pl = strlen(p)+1))) {
+                       ds.pages = ds.offset = 0;
+                       ds.name = getChunk(pl);
+                       memcpy(data+ds.name, p, pl);
+                       ds.type = NC_DIR;
+#ifdef NC_DEBUG_INSERT
+                       fprintf(stderr, "Insertion parent 2: %p\n", DE(sdo));
+#endif
+                       // FIXME: crc calculation
+                       sdo = ((char *)insert(sdo, &ds)) - data;
+                       p += pl;
+               }
+               ds.type = t;
+               memcpy(data+(ds.name = getChunk(pl)), p, pl);
+               ds.pages = ds.offset = 0;
+#ifdef NC_DEBUG_INSERT
+               fprintf(stderr, "Insertion parent 1: %p\n", DE(sdo));
+#endif
+               nd = insert(sdo, &ds);
+               sb->modtime++;
+               free(parse);
+       } else
+               if (nd->type != t) {
+                       unLockFile();
+                       return NC_ERR_TYPE;
+               }
+       unsigned ndo = ((char *)nd) - data;
+       if (t != NC_DIR) {
+               if (value) {
+                       if (nd->offset && CS(nd->offset)-sizeof(unsigned) < len) {
+                               freeChunk(nd->offset);
+                               nd = DE(ndo);
+                               nd->offset = 0;
+                       }
+                       if (nd->offset) {
+                               if (CS(nd->offset)-sizeof(unsigned) > alignSize(len)+sizeof(unsigned)) {
+                                       unsigned trim = CS(nd->offset) - alignSize(len) - sizeof(unsigned);
+                                       unsigned off = nd->offset + alignSize(len) + sizeof(unsigned);
+                                       CS(off) = trim;
+                                       CS(nd->offset) -= trim;
+                                       freeChunk(off);
+                                       nd = DE(ndo);
+                               }
+                       } else {
+                               unsigned off = getChunk(len);
+                               nd = DE(ndo);
+                               nd->offset = off;
+                       }
+                       memcpy(data+nd->offset, value, len);
+                       nd->pages = len;
+               } else
+                       if (nd->offset) {
+                               freeChunk(nd->offset);
+                               DE(ndo)->offset = 0;
+                       }
+       } else
+               // Preallocate pages for directory
+               if (len > nd->pages) {
+                       unsigned off = getChunk(sizeof(unsigned)*len);
+                       if (DE(ndo)->offset) {
+                               memcpy(data+off, data+DE(ndo)->offset, sizeof(unsigned)*(DE(ndo)->pages));
+                               freeChunk(DE(ndo)->offset);
+                       }
+                       DE(ndo)->offset = off;
+                       for (unsigned al = len - DE(ndo)->pages; al; al--) {
+                               off = getChunk(sizeof(struct nc_de_s));
+                               ((unsigned *)(data+DE(ndo)->offset))[DE(ndo)->pages++] = off;
+                       }
+               }
+       unLockFile();
+#ifdef NC_DEBUG_INSERT
+       fprintf(stderr, "%p\n", cdir);
+#endif
+       return NC_ERR_OK;
+}
+
+char *NConfig::getName(const struct nc_de_s *w)
+{
+       if (w == rdir)
+               return strdup("/");
+       char *parent = getName(DE(w->parent));
+       unsigned l1 = strlen(parent);
+       unsigned l2 = strlen(data+w->name)+1;
+
+       parent = (char *) realloc(parent, l1 + l2 + (l1 == 1 ? 0 : 1));
+       if (l1 != 1) {
+               memcpy(parent+l1, "/", 2);
+               l1++;
+       }
+       memcpy(parent+l1, data+w->name, l2);
+       return parent;
+}
+
+int NConfig::chDir(const char *name)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+
+       int ret = NC_ERR_OK;
+       struct nc_de_s *nd = getDirEnt(name);
+       if (nd) {
+               if (nd->type == NC_DIR) {
+                       cdir = nd;
+                       free(cname);
+                       cname = getName(cdir);
+               } else
+                       ret = NC_ERR_NDIR;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+const char *NConfig::pwDir()
+{
+       if (fd < 0)
+               return NULL;
+       lockFile(NC_L_RO);
+       struct nc_de_s *l = cdir;
+       char * ret = strdup(data+l->name);
+       while (DE(l->parent) != l) {
+               unsigned len = CS(l->name);
+               char *r = (char *) malloc(strlen(ret) + len + 2);
+               memcpy(r, data+l->name, len);
+               if (*ret != '/' && DE(l->parent) != rdir)
+                       strcat(r, "/");
+               strcat(r, ret);
+               free(ret);
+               ret = r;
+               l = DE(l->parent);
+       }
+       unLockFile();
+       return ret;
+}
+
+struct nc_de_s *NConfig::getDirEnt(const char *name, struct nc_de_s *cc)
+{
+       struct nc_de_s *ret = cc ? cc : ((*name == '/') ? rdir : cdir);
+       char *c = canonize(name), *can;
+
+       if (!(can = c))
+               return ret;
+       while (*c) {
+               if (!strcmp(c, ".."))
+                       ret = DE(ret->parent);
+               else
+                       if (strcmp(c, ".")) {
+                               struct nc_de_s *re = ret;
+                               int left = 0, right = ret->pages-1, p, r;
+
+                               ret = NULL;
+                               while (left <= right) {
+                                       p = (left + right) / 2;
+                                       r = strcmp(c, data+IDE(re, p)->name);
+                                       if (r < 0) {
+                                               left = p + 1;
+                                               continue;
+                                       }
+                                       if (!r) {
+                                               ret = IDE(re, p);
+                                               break;
+                                       }
+                                       right = p - 1;
+                               }
+                       }
+               c += strlen(c)+1;
+               if (!ret || (*c && ret->type != NC_DIR)) {
+                       ret = NULL;
+                       break;
+               }
+       }
+       free(can);
+       return ret;
+}
+
+char *NConfig::canonize(const char *name)
+{
+       if (*name == '/')
+               name++;
+       size_t i = strlen(name);
+       char *ret = (char *)calloc(1, i+3);
+       memcpy(ret, name, i);
+       for (size_t j=0; j<i; j++)
+               if (ret[j] == '/')
+                       ret[j] = 0;
+       return ret;
+}
+
+struct nc_de_s *NConfig::insert(unsigned where, struct nc_de_s *what)
+{
+#ifdef NC_DEBUG_INSERT
+       fprintf(stderr, "Insertion: %s %d\n", data+what->name, what->type);
+#endif
+       struct nc_de_s *w = DE(where);
+       if (!DE(where)->offset || IDE(w, w->pages-1)->type) {
+               unsigned a = getChunk((w->pages+sb->ent_inc)*sizeof(unsigned));
+               w = DE(where);
+               if (w->offset) {
+                       memcpy(data+a, data+w->offset, w->pages*sizeof(unsigned));
+                       freeChunk(w->offset);
+                       w = DE(where);
+               }
+               w->offset = a;
+               for (unsigned ha = 0; ha<sb->ent_inc; ha++) {
+                       unsigned off = getChunk(sizeof(struct nc_de_s));
+                       w = DE(where);
+                       ((unsigned *)(data+w->offset))[w->pages] = off;
+                       w->pages++;
+               }
+       }
+       int i = 0, l = 0, r = w->pages - 1, c;
+       while (l <= r) {
+               c = (l + r) / 2;
+               if (!IDE(w, c)->type || strcmp(data+what->name, data+IDE(w, c)->name) > 0) {
+                       i = c;
+                       r = c - 1;
+               } else
+                       l = c + 1;
+       }       
+
+#ifdef NC_DEBUG_INSERT
+       fprintf(stderr, "Insertion to slot %u (%s)\n", i, data+what->name);
+#endif
+       what->parent = where;
+       unsigned to = ((unsigned *)(data+w->offset))[w->pages-1];
+       memmove(((unsigned *)(data+w->offset))+i+1, ((unsigned *)(data+w->offset))+i, sizeof(unsigned)*(w->pages-i-1));
+       ((unsigned *)(data+w->offset))[i] = to;
+       void *ret = memcpy(DE(to), what, sizeof(struct nc_de_s));
+       sb->modtime++;
+       return (struct nc_de_s *)ret;
+}
+
+void NConfig::status()
+{
+       if (fd < 0)
+               return;
+       lockFile(NC_L_RO);
+       fprintf(stderr, "Size:\t%u\n", sb->size);
+       unsigned low=0, hi=chunks[0].size, cnt=0, ttl=0;
+       for (unsigned i=0; i<sb->chunk_ttl; i++)
+               if (chunks[i].size > 0) {
+                       if (!low || low > chunks[i].size)
+                               low = chunks[i].size;
+                       ttl += chunks[i].size;
+                       cnt++;
+               }
+       unLockFile();
+       fprintf(stderr, "Free:\t%u in %u chunk%s\n", ttl, cnt, cnt > 1 ? "s" : "");
+       if (cnt > 0)
+               fprintf(stderr, "Min:\t%u\nAvg:\t%u\nMax:\t%u\n", low, ttl / cnt, hi);
+}
+       
+struct nc_ls_s *NConfig::ls(const char *name)
+{
+       if (fd < 0)
+               return NULL;
+       lockFile(NC_L_RO);
+
+       struct nc_ls_s *rt = NULL;
+       unsigned count = 0;
+       struct nc_de_s *de = NULL;
+       struct nc_de_s *ds = name ? getDirEnt(name) : cdir;
+
+       if (ds && ds->type == NC_DIR) {
+               for (unsigned i=0; i<ds->pages; i++) {
+                       de = IDE(ds, i);
+                       if (de->type && de->name) {
+                               rt = (struct nc_ls_s *) realloc(rt, (count+2)*sizeof(nc_ls_s));
+                               rt[count].type = de->type;
+                               rt[count].name = strdup(data+de->name);
+                               rt[++count].type = 0;
+                               rt[count].name = NULL;
+                       }
+               }
+       }
+       unLockFile();
+       return rt;
+}
+
+void NConfig::fast_free(unsigned offset)
+{
+       unsigned s = CS(offset), i = 0;
+       offset -= sizeof(unsigned);
+
+       while (1) {
+               if (!chunks[i].size) {
+#ifdef NC_DEBUG_ALLOC
+                       fprintf(stderr, "Inserting %u:%u to %u\n", offset, s, i);
+#endif
+                       chunks[i].offset = offset;
+                       chunks[i].size = s;
+                       break;
+               }
+               if (chunks[i].offset == offset + s) {
+#ifdef NC_DEBUG_ALLOC
+                       fprintf(stderr, "Prepending %u:%u to %u (%u:%u)\n", offset, s, i, chunks[i].offset, chunks[i].size);
+#endif
+                       chunks[i].offset -= s;
+                       chunks[i].size += s;
+                       break;
+               }
+               if (offset == chunks[i].offset + chunks[i].size) {
+#ifdef NC_DEBUG_ALLOC
+                       fprintf(stderr, "Appending  %u:%u to %u (%u:%u)\n", offset, s, i, chunks[i].offset, chunks[i].size);
+#endif
+                       chunks[i].size += s;
+                       break;
+               }
+               i++;
+       }
+
+       // Keep the array sorted
+       while (i && chunks[i].size > chunks[i-1].size) {
+               unsigned b = chunks[i].size;
+               unsigned j = i - 1;
+               chunks[i].size = chunks[j].size;
+               chunks[j].size = b;
+               b = chunks[i].offset;
+               chunks[i].offset = chunks[j].offset;
+               chunks[j].offset = b;
+               i = j;
+       }
+}
+
+int NConfig::renameKey(const char *oldname, const char *newname)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       if (omode != NC_O_RW)
+               return NC_ERR_RDONLY;
+       lockFile(NC_L_RW);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *parent, *nd = getDirEnt(newname);
+       if (nd) {
+               if ((nd = getDirEnt(oldname))) {
+                       size_t len = strlen(newname)+1;
+                       int inc = strcmp(oldname, newname);
+                       unsigned i, off, pos, ndo = ((char *)nd) - data;
+                       if (alignSize(len) != CS(nd->name)) {
+                               freeChunk(nd->name);
+                               off = getChunk(len);
+                               DE(ndo)->name = off;
+                               nd = DE(ndo);
+                       }
+                       memcpy(data+nd->name, newname, len);
+                       parent = DE(nd->parent);
+                       for (pos = 0; pos < parent->pages && IDE(parent, pos) != nd; pos++)
+                               ;
+                       for (i = pos; i>=0 && i<parent->pages; i += inc)
+                               if (strcmp(data+IDE(parent, i)->name, newname) != inc)
+                                       break;
+                       if (inc == -1)
+                               memmove(((unsigned *)(data+parent->offset))+i+1,
+                                       ((unsigned *)(data+parent->offset))+i,
+                                       sizeof(unsigned)*(pos - i));
+                       else
+                               memmove(((unsigned *)(data+parent->offset))+pos,
+                                       ((unsigned *)(data+parent->offset))+pos+1,
+                                       sizeof(unsigned)*(i-pos));
+                       ((unsigned *)(data+parent->offset))[i] = ndo;
+                       sb->modtime++;
+               } else
+                       ret = NC_ERR_NEXIST;
+       } else
+               ret = NC_ERR_PERM;
+       unLockFile();
+       return NC_ERR_OK;
+}
+
+int NConfig::createDir(const char *name, unsigned entries)
+{
+       return _setKey(name, NC_DIR, NULL, entries);
+}
+
+int NConfig::setKey(const char *name, const unsigned long long value)
+{
+       return _setKey(name, NC_UINT, (const char *)&value, sizeof(value));
+}
+
+int NConfig::setKey(const char *name, const unsigned value)
+{
+       unsigned long long b = value;
+       return _setKey(name, NC_UINT, (const char *)&b, sizeof(b));
+}
+
+int NConfig::setKey(const char *name, const signed long long value)
+{
+       return _setKey(name, NC_INT, (const char *)&value, sizeof(value));
+}
+
+int NConfig::setKey(const char *name, const int value)
+{
+       signed long long b = value;
+       return _setKey(name, NC_INT, (const char *)&b, sizeof(b));
+}
+
+int NConfig::setKey(const char *name, const char *value)
+{
+       return _setKey(name, NC_STRING, value, strlen(value)+1);
+}
+
+int NConfig::setKey(const char *name, const long double value)
+{
+       return _setKey(name, NC_DOUBLE, (const char *)&value, sizeof(value));
+}
+
+int NConfig::setKey(const char *name, const double value)
+{
+       long double b = value;
+       return _setKey(name, NC_DOUBLE, (const char *)&b, sizeof(b));
+}
+
+int NConfig::setKey(const char *name, const char *value, const unsigned len)
+{
+       if (!value && len)
+               return NC_ERR_NVAL;
+       if (!len)
+               return _setKey(name, NC_RAW, NULL, 0);
+       return _setKey(name, NC_RAW, value, len);
+}
+
+int NConfig::getKey(const char *name, unsigned long long &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_UINT) {
+                       memcpy(&value, data+k->offset, sizeof(value));
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, unsigned &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_UINT) {
+                       unsigned long long b;
+                       memcpy(&b, data+k->offset, sizeof(b));
+                       value = b;
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, long double &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_DOUBLE) {
+                       memcpy(&value, data+k->offset, sizeof(value));
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, double &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_DOUBLE) {
+                       long double b;
+                       memcpy(&b, data+k->offset, sizeof(b));
+                       value = b;
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, signed long long &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_INT) {
+                       memcpy(&value, data+k->offset, sizeof(value));
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, int &value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_INT) {
+                       signed long long b;
+                       memcpy(&b, data+k->offset, sizeof(b));
+                       value = b;
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, char *&value)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_STRING) {
+                       if (k->offset) {
+                               if (!(value = strdup(data+k->offset)))
+                                       ret = NC_ERR_NMEM;
+                       } else
+                               value = NULL;
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+int NConfig::getKey(const char *name, char *&value, unsigned &len)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       lockFile(NC_L_RO);
+       int ret = NC_ERR_OK;
+       struct nc_de_s *k = getDirEnt(name);
+       if (k) {
+               if (k->type == NC_RAW) {
+                       if (k->offset) {
+                               len = k->pages;
+                               value = (char *)malloc(len);
+                               memcpy(value, data+k->offset, len);
+                       } else {
+                               len = 0;
+                               value = NULL;
+                       }
+               } else
+                       ret = NC_ERR_TYPE;
+       } else
+               ret = NC_ERR_NEXIST;
+       unLockFile();
+       return ret;
+}
+
+void NConfig::lockFile(int type, int force)
+{
+#ifdef NC_DEBUG_LOCK
+       fprintf(stderr, "Lock called type=%d force=%d lock=%d olck=%u\n", type, force, lock, olck);
+#endif
+       if (lock == NC_L_RO && type == NC_L_RW) {
+               fprintf(stderr, "Lock promotion is not possible.\n");
+               abort();
+       }
+       if (lock != NC_L_NONE) {
+               olck++;
+               return;
+       }
+       
+       struct flock flc = { type == NC_L_RW ? F_WRLCK : F_RDLCK, SEEK_SET, 0, 0, 0 };
+       while (fcntl(fd, F_SETLKW, &flc)) {
+               sched_yield();
+               flc.l_type = type == NC_L_RW ? F_WRLCK : F_RDLCK;
+               flc.l_whence = SEEK_SET;
+               flc.l_len = flc.l_start = 0;
+       }
+
+#ifdef NC_DEBUG_LOCK
+       fprintf(stderr, "Locked %u %u %s\n", sb->modtime, update, force ? "forced." : "");
+#endif
+       if (careful && type == NC_L_RW)
+               mprotect(data, sb->size, PROT_READ | PROT_WRITE);
+       lock = type;
+       olck = 0;
+       if (sb->modtime != update || force) {
+               // refresh memory mapping
+               if (lsize != sb->size) {
+                       _remap(lsize, sb->size);
+                       lsize = sb->size;
+                       chunks = CM(sb->chunk);
+               }
+               cdir = getDirEnt(cname);
+               update = sb->modtime;
+       }
+}
+
+void NConfig::unLockFile()
+{
+#ifdef NC_DEBUG_LOCK
+       fprintf(stderr, "UnLock called lock=%u olck=%u\n", lock, olck);
+#endif
+       if (olck) {
+               olck--;
+               return;
+       }
+       if (lock == NC_L_NONE)
+               return;
+       struct flock flc = {F_UNLCK, SEEK_SET, 0, 0, 0 };
+       update = sb->modtime;
+#ifdef NC_DEBUG_LOCK
+       fprintf(stderr, "Unlock %u\n", update);
+#endif
+       if (careful)
+               mprotect(data, sb->size, PROT_READ);
+       fcntl(fd, F_SETLK, &flc);
+       lock = NC_L_NONE;
+       olck = 0;
+}
+
+void NConfig::_remap(const size_t osize, const size_t nsize)
+{
+       data = (char *) mremap(data, osize, nsize, 1);
+       if (data == MAP_FAILED) {
+               perror("mremap");
+               abort();
+       }
+       sb = SB;
+       rdir = DE(sb->root);
+}
+
+char * NConfig::version()
+{
+       return strdup("EliteDVB registry");
+}
+
diff --git a/lib/base/nconfig.h b/lib/base/nconfig.h
new file mode 100644 (file)
index 0000000..12a3c6c
--- /dev/null
@@ -0,0 +1,392 @@
+#ifndef NC_NCONFIG_H
+#define NC_NCONFIG_H   1
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Superblock definitions
+ */
+#define NC_SB_MAGIC            ("\0\11\22")                    // Superblock identifier
+
+/*
+ * Key type definitions
+ */
+#define NC_DIR                 0x01    // The key is a directory
+#define NC_STRING              0x02    // The key contains a string
+#define NC_INT                 0x03    // The key contains a signed integer
+#define NC_UINT                        0x04    // The key contains an unsigned integer
+#define NC_RAW                 0x05    // The key contains raw data
+#define NC_DOUBLE              0x06    // The key contains a double
+#define NC_LINK                        0x07    // The key points somewhere else
+
+/*
+ * File access definitions
+ */
+#define NC_O_RO                        0x01    // Open file in read-only mode
+#define NC_O_RW                        0x02    // Open file in read-write mode
+
+/*
+ * Lock types
+ */
+#define NC_L_NONE              0x00    // No lock
+#define NC_L_RO                        0x01    // Read-only lock
+#define        NC_L_RW                 0x02    // Read-write lock
+
+/*
+ * Error codes
+ */
+#define NC_ERR_OK                      0               // Everything is OK
+#define NC_ERR_TYPE             -1             // Type mismatch
+#define NC_ERR_NDIR             -2             // Key is not a directory
+#define NC_ERR_PERM             -3             // Operation is not allowed
+#define NC_ERR_NMEM             -4             // Not enough memory to complete operation
+#define NC_ERR_NEXIST   -5             // Key does not exist
+#define NC_ERR_NFILE    -6             // No file is assigned/open
+#define NC_ERR_CORRUPT -7              // File is corrupted
+#define NC_ERR_NVAL             -8             // Invalid value
+#define NC_ERR_RDONLY   -9             // File is open in read-only mode
+#define NC_ERR_NOSUPPORT -10   // Support is not compiled-in
+
+/*
+ * Truth value definitions
+ */
+#ifndef TRUE
+#define TRUE                   1
+#endif
+#ifndef FALSE
+#define FALSE                  0
+#endif
+
+/*
+ * Header of the config file.
+ */
+struct nc_sb_s {
+       char magic[4];          // superblock magic
+       unsigned size;          // Current file size
+       unsigned ent_inc;       // directory increment
+       unsigned chunk_inc;     // Memory chunks increment
+       unsigned size_inc;      // file size increment
+       unsigned chunk_ttl;     // size of chunkmap
+       unsigned chunk;         // pointer to chunkmap
+       unsigned root;          // pointer to root direntry
+       unsigned modtime;       // file version
+};
+
+/*
+ * Free chunk descriptor
+ */
+struct nc_chunk_s {
+       unsigned offset;
+       unsigned size;
+};
+
+/*
+ *  In-file directory entry
+ */
+struct nc_de_s {
+       unsigned name;
+       unsigned type;
+       unsigned parent;
+       unsigned offset;
+       unsigned pages;
+       unsigned crc;
+};
+
+/*
+ * Ls reporting
+ */
+struct nc_ls_s {
+       const char *name;
+       unsigned type;
+};
+
+class NConfig
+{
+public:
+               /*
+                * Class constructor
+                * pass TRUE as parameter to enable
+                * write protection when leaving library
+                */
+               NConfig(int protect = FALSE);
+               virtual ~NConfig();
+               
+               /*
+                * Set file name (prior to open)
+                * Errors:
+                * NC_ERR_PERM  file is already open
+                * NC_ERR_NVAL  no file name is given
+                */
+               int setName(const char *name);
+
+               /*
+                * Open the configuration file, re-open it
+                * Errors:
+                * NC_ERR_NFILE         no file name is assigned
+                * NC_ERR_TYPE          file open mode is invalid
+                * NC_ERR_PERM          file cannot be opened/created
+                * NC_ERR_NMEM          unable to mmap the file
+                * NC_ERR_CORRUPT       superblock magic mismatch
+                */
+               int open(const int how = NC_O_RW);
+
+               /*
+                * Close the configuration file
+                * No errors defined
+                */
+               void close();
+               
+               void flush(); // flush file if not mmap'ed
+               
+               /*
+                * Create a new file
+                * resize is filesize increment is system pages
+                * dirent is directory increment
+                * mchunks is memory block increment
+                * Errors:
+                * NC_ERR_PERM          file already exists
+                * NC_ERR_NFILE         cannot create new file
+                * NC_ERR_NVAL          file is already open
+                */
+               int createNew(unsigned resize = 4, unsigned dirent = 32, unsigned mchunks = 32);
+
+               /*
+                * Get an unsigned integer
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_TYPE          the key exists, but is of different type
+                */
+               int getKey(const char *name, unsigned &value);
+               int getKey(const char *name, unsigned long long &value);
+
+               /*
+                * Get a signed integer
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_TYPE          the key exists, but is of different type
+                */
+               int getKey(const char *name, int &value);
+               int getKey(const char *name, signed long long &value);
+
+               /*
+                * Get a string
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_TYPE          the key exists, but is of different type
+                */
+               int getKey(const char *name, char *&value);
+
+               /*
+                * Get a long double
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_TYPE          the key exists, but is of different type
+                */
+               int getKey(const char *name, double &value);
+               int getKey(const char *name, long double &value);
+               
+               /*
+                * Get raw data
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_TYPE          the key exists, but is of different type
+                */
+               int getKey(const char *name, char *&value, unsigned &len);
+
+               /*
+                * Insert an unsigned integer
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not an usigned integer
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int setKey(const char *name, const unsigned value);
+               int setKey(const char *name, const unsigned long long value);
+               
+               /*
+                * Insert an integer
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not a signed integer
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int setKey(const char *name, const int value);
+               int setKey(const char *name, const signed long long value);
+               
+               /*
+                * Insert a string
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not a string
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int setKey(const char *name, const char *value);
+
+               /*
+                * Insert raw data
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not raw data
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int setKey(const char *name, const char *value, const unsigned len);
+               
+               /*
+                * Insert a double
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not raw data
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int setKey(const char *name, const double value);
+               int setKey(const char *name, const long double value);
+               
+               /*
+                * Rename a key
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open read-only
+                * NC_ERR_NEXIST        the key does not exist
+                * NC_ERR_PERM          key with specified name already exists
+                */
+               int renameKey(const char *oldname, const char *newname);
+
+               /*
+                * Delete a key
+                * No errors defined
+                */
+               void delKey(const char *name);
+
+               /*
+                * Create a directory
+                * entries parameter specifies number of direntries to preallocate
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_RDONLY        file is open in read-only mode
+                * NC_ERR_PERM          intermediate key is not a directory
+                * NC_ERR_TYPE          key already exists, but is not a directory
+                * NC_ERR_NEXIST        key does not exist (should NEVER happen)
+                */
+               int createDir(const char *name, unsigned entries = 0);
+
+               /*
+                * Change working directory
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_NDIR          target key is not a directory
+                * NC_ERR_NEXIST        target key direcotry does not exist
+                */
+               int chDir(const char *name);
+
+               /*
+                * Print working directory
+                * Errors:
+                * Returns NULL on error
+                */
+               const char *pwDir();
+
+               /*
+                * List all keys in current/specified directory
+                * Result is a NULL-terminated array of nc_ls_s
+                * structures.
+                * Errors:
+                * Returns NULL on error
+                * Note:
+                * You need to free the returned pointer,
+                * as well as all the names in it.
+                */
+               struct nc_ls_s *ls(const char *dir = NULL);
+       
+               /*
+                * Lock file
+                * This will block until lock becomes available
+                * type is either:
+                *              NC_L_RO for read-only lock
+                *              NC_L_RW for read-write lock
+                * No errors defined
+                *
+                * NOTE: lock may get promoted
+                */
+               void lockFile(int type, int force = FALSE);
+
+               /*
+                * Unlock file
+                * No errors defined
+                */
+               void unLockFile();
+       
+               /*
+                * Print out (to stderr) information about current file
+                * No errors defined
+                */
+               void status();
+
+               /*
+                * Return version string
+                */
+               static char *version();
+
+               /*
+                * Dump current file to XML
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_PERM          could not write XML output
+                */
+               int toXML(const char *filename);
+
+               /*
+                * Load XML to current file
+                * a file has to be open
+                * force can be
+                *      TRUE - existing keys will be deleted
+                *      FALSE - import will ignore a key if existing key type conflicts
+                * Errors:
+                * NC_ERR_NFILE         no file is open
+                * NC_ERR_PERM          file is open read-only
+                */
+               int fromXML(const char *filename, int force = TRUE);
+               
+protected:
+               int fd, omode, lock, careful;
+               char *fname, *data, *cname;
+               unsigned lsize, update;
+               unsigned revision, olck;
+               struct nc_sb_s *sb;
+               struct nc_de_s *rdir, *cdir;
+               struct nc_chunk_s *chunks;
+               
+               int _setKey(const char *, const unsigned, const char *, const unsigned);
+               void _delKey(const char *, struct nc_de_s *, int);
+               void expand(unsigned);
+               
+               void fast_free(unsigned);
+
+               unsigned getChunk(unsigned);
+               void freeChunk(unsigned);
+               static inline unsigned alignSize(unsigned);
+
+               struct nc_de_s *getDirEnt(const char *, struct nc_de_s * = NULL);
+               struct nc_de_s *insert(unsigned, struct nc_de_s *);
+               char *canonize(const char *);
+               char *getName(const struct nc_de_s *);
+
+               void _remap(const size_t, const size_t);
+
+               inline unsigned crc(const char *, unsigned);
+               void store(nc_de_s *, FILE *);
+               void restore(void *, int);
+};
+
+#endif /* NC_NCONFIG_H */
+
diff --git a/lib/base/nxml.cpp b/lib/base/nxml.cpp
new file mode 100644 (file)
index 0000000..f32880a
--- /dev/null
@@ -0,0 +1,339 @@
+#include <lib/base/nconfig.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_LIBXML2
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#else
+#define xmlChar char
+#endif /* HAVE_LIBXML2 */
+
+#define DE(x)          ((struct nc_de_s *) (data+(x)))
+#define IDE(x, y)      (DE(((unsigned *) (data+(x)->offset))[(y)]))
+#define XML_DE         ((const xmlChar *) "dirEntry")
+#define XML_NS         ((const xmlChar *) "http://hq.alert.sk/projects/nconfig")
+#define XML_ROOT       ((const xmlChar *) "NConfigExport")
+
+static char *encodeXml(const char *what)
+{
+       unsigned p = 0, size = 6*strlen(what)+1;
+       char *ret = (char *)malloc(size);
+       for (; *what; what++) {
+               switch (*what) {
+               case '"':
+                       ret[p++] = '&';
+                       ret[p++] = 'q';
+                       ret[p++] = 'u';
+                       ret[p++] = 'o';
+                       ret[p++] = 't';
+                       ret[p++] = ';';
+                       continue;
+               case '>':
+                       ret[p++] = '&';
+                       ret[p++] = 'q';
+                       ret[p++] = 't';
+                       ret[p++] = ';';
+                       continue;
+               case '<':
+                       ret[p++] = '&';
+                       ret[p++] = 'l';
+                       ret[p++] = 't';
+                       ret[p++] = ';';
+                       continue;
+               case '&':
+                       ret[p++] = '&';
+                       ret[p++] = 'a';
+                       ret[p++] = 'm';
+                       ret[p++] = 'p';
+                       ret[p++] = ';';
+                       continue;
+               }
+               if (*what >= 0x20 || *what == '\n' || *what == '\r' || *what == '\t')
+                       ret[p++] = *what;
+               else
+                       p += sprintf(ret+p, "&#%d;", *what);
+       }
+       ret[p] = '\0';
+       return ret;
+}
+
+void NConfig::store(nc_de_s *de, FILE *f)
+{
+       struct nc_de_s *cc;
+       for (unsigned i=0; i<de->pages; i++)
+               if ((cc = IDE(de, i))->type) {
+                       char *encname = encodeXml(data+cc->name);
+                       fprintf(f, "<nc:%s name=\"%s\" type=\"%d\" value=\"", XML_DE, encname, cc->type);
+                       free(encname);
+                       switch (cc->type) {
+                       case NC_DIR:
+                               fprintf(f, "%u\">\n", cc->pages);
+                               store(cc, f);
+                               fprintf(f, "</nc:%s>\n", XML_DE);
+                               break;
+                       case NC_STRING:
+                               fprintf(f, "%s\"/>\n", encname = encodeXml(data+cc->offset));
+                               free(encname);
+                               break;
+                       case NC_INT:
+                               fprintf(f, "%lld\"/>\n", *((signed long long *) (data+cc->offset)));
+                               break;
+                       case NC_UINT:
+                               fprintf(f, "%llu\"/>\n", *((unsigned long long *) (data+cc->offset)));
+                               break;
+                       case NC_DOUBLE:
+                               fprintf(f, "%La\"/>\n", *((long double *) (data+cc->offset)));
+                               break;
+                       case NC_RAW:
+                               {
+                                       const char *raw = data+cc->offset;
+                                       for (unsigned j=0; j<cc->pages; j++)
+                                               fprintf(f, "%d%d%d", raw[j] / 100, (raw[j] % 100) / 10, raw[j] % 10);
+                                       fprintf(f, "\"/>\n");
+                               }
+                       }
+               }
+}
+
+int NConfig::toXML(const char *filename)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+
+       FILE *f = fopen(filename, "w");
+       if (!f)
+               return NC_ERR_PERM;
+       
+       fprintf(f, "%s", "<?xml version=\"1.0\"?>\n");
+       fprintf(f, "<nc:%s xmlns:nc=\"%s\" libVersion=\"%s\"", XML_ROOT, XML_NS, VERSION);
+#ifdef HAVE_TIME_H
+    time_t t = time(NULL);
+    char *tim = ctime(&t);
+    tim[strlen(tim)-1] = 0;
+       fprintf(f, " time=\"%s\"", tim);
+#endif /* HAVE_TIME_H */
+       fprintf(f, ">\n");
+       lockFile(NC_L_RO);
+
+       store(rdir, f);
+
+       unLockFile();
+       fprintf(f, "</nc:%s>\n", XML_ROOT);
+       fclose(f);
+       return NC_ERR_OK;
+}
+
+#ifdef HAVE_LIBXML2
+static xmlSAXHandler sh;
+enum stateEnum {noRoot = 0, inRoot, inDir, inEnt, unknown};
+
+struct ncParseState {
+       stateEnum state, pState;
+       xmlChar *ns;
+       unsigned depth;
+       unsigned unDepth;
+       unsigned force;
+       NConfig *which;
+};
+
+static int ncXmlSAXParseFile(xmlSAXHandlerPtr sax, void *user_data, const char *filename)
+{
+       int ret = 0;
+       xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename);
+       if (!ctxt)
+               return -1;
+       ctxt->sax = sax;
+       ctxt->userData = user_data;
+       xmlParseDocument(ctxt);
+       ret = ctxt->wellFormed ? 0 : -1;
+       if (sax)
+               ctxt->sax = NULL;
+       xmlFreeParserCtxt(ctxt);
+       return ret;
+}
+
+static xmlEntityPtr ncXmlGetEntity(void *user_data, const CHAR *name)
+{
+       return xmlGetPredefinedEntity(name);
+}
+
+static void ncXmlStartElement(void *user_data, const CHAR *name, const CHAR **attrs)
+{
+       struct ncParseState *p = (struct ncParseState *)user_data;
+#ifdef NC_DEBUG_XML
+       fprintf(stderr, "New element %s state=%d %s\n", name, p->state, p->ns);
+#endif
+       if (p->state == unknown) {
+               p->unDepth++;
+               return;
+       }
+       if (p->state == noRoot) {
+               while (*attrs) {
+                       if (!xmlStrncmp(*attrs, (const xmlChar *) "xmlns:", 6)) {
+                               if (!xmlStrcmp(attrs[1], XML_NS)) {
+                                       p->ns = xmlStrdup((*attrs)+6);
+                                       break;
+                               }
+                       }
+                       attrs += 2;
+               }
+               char *b = (char *) malloc(xmlStrlen(p->ns)+xmlStrlen(XML_ROOT)+2);
+               sprintf(b, "%s:%s", p->ns, XML_ROOT);
+               if (xmlStrcmp(name, (xmlChar *)b)) {
+#ifdef NC_DEBUG_XML
+                       fprintf(stderr, "NewElement, entering unknown %s\n", name);
+#endif
+                       p->pState = p->state;
+                       p->state = unknown;
+               } else
+                       p->state = inRoot;
+               free(b);
+               return;
+       }
+       if (p->state == inRoot || p->state == inDir) {
+               const xmlChar *value = NULL, *n = NULL;
+               int type = 0;
+               while (*attrs) {
+                       if (!xmlStrcmp(*attrs, (const xmlChar *)"value"))
+                               value = attrs[1];
+                       if (!xmlStrcmp(*attrs, (const xmlChar *)"name"))
+                               n = attrs[1];
+                       if (!xmlStrcmp(*attrs, (const xmlChar *)"type"))
+                               type = atoi(attrs[1]);
+                       attrs += 2;
+               }
+#ifdef NC_DEBUG_XML
+               fprintf(stderr, "%s %s %s %d %d\n", name, n, value, type, p->state);
+#endif
+               char *b = (char *) malloc(xmlStrlen(p->ns)+xmlStrlen(XML_DE)+2);
+               sprintf(b, "%s:%s", p->ns, XML_DE);
+               if (xmlStrcmp(name, (xmlChar *)b) || !type || !value || !n) {
+#ifdef NC_DEBUG_XML
+                       fprintf(stderr, "NewElement, entering unknown on mismatch\n");
+#endif
+                       p->pState = p->state;
+                       p->state = unknown;
+                       free(b);
+                       return;
+               }
+               free(b);
+               if (p->force)
+                       p->which->delKey((const char *)n);
+
+               switch (type) {
+               case NC_DIR:
+                       if (p->which->createDir((const char *)n, strtoul((const char *)value, NULL, 0)) != NC_ERR_OK) {
+                               p->pState = p->state;
+                               p->state = unknown;
+#ifdef NC_DEBUG_XML
+                               fprintf(stderr, "NewElement, entering unknown on failed mkdir\n");
+#endif
+                               return;
+                       }
+                       p->which->chDir((const char *)n);
+                       break;
+               case NC_STRING:
+                       p->which->setKey((const char *)n, (const char *)value);
+                       break;
+               case NC_INT:
+                       p->which->setKey((const char *)n, strtoll((const char *)value, NULL, 0));
+                       break;
+               case NC_UINT:
+                       p->which->setKey((const char *)n, strtoull((const char *)value, NULL, 0));
+                       break;
+               case NC_DOUBLE:
+                       {
+                               long double c;
+                               sscanf((const char *)value, "%La", &c);
+                               p->which->setKey((const char *)n, c);
+                       }
+                       break;
+               case NC_RAW:
+                       {
+                               unsigned size = xmlStrlen(value) / 3;
+                               char *dec = NULL;
+                               if (size) {
+                                       dec = (char *)malloc(size);
+                                       for (unsigned i=0, k=0; i<size; i++, k += 3)
+                                               dec[i] = value[k] * 100 + value[k+1] * 10 + value[k+2];
+                               }
+                               p->which->setKey((const char *)n, dec, size);
+                               free(dec);
+                       }
+               }
+               if (type == NC_DIR) {
+                       p->state = inDir;
+                       p->depth++;
+               } else {
+                       p->pState = p->state;
+                       p->state = inEnt;
+               }
+               return;
+       }
+}
+
+static void ncXmlEndElement(void *user_data, const CHAR *name)
+{
+       struct ncParseState *p = (struct ncParseState *)user_data;
+#ifdef NC_DEBUG_XML
+       fprintf(stderr, "EndElement %s %s %d\n", name, p->ns, p->state);
+#endif
+       if (p->state == inEnt) {
+               p->state = p->pState;
+               return;
+       }
+       if (p->state == unknown) {
+               if (p->unDepth)
+                       p->unDepth--;
+               else
+                       p->state = p->pState;
+               return;
+       }
+       if (p->state == inRoot) {
+               p->state = noRoot;
+               free(p->ns);
+               p->ns = NULL;
+               return;
+       }
+       if (p->state == inDir) {
+               p->depth--;
+               if (!p->depth)
+                       p->state = inRoot;
+               p->which->chDir("..");
+       }
+}
+#endif /* HAVE_LIBXML2 */
+
+int NConfig::fromXML(const char *filename, int force)
+{
+       if (fd < 0)
+               return NC_ERR_NFILE;
+       if (omode != NC_O_RW)
+               return NC_ERR_PERM;
+#ifndef HAVE_LIBXML2
+       return NC_ERR_NOSUPPORT;
+#else
+       struct ncParseState state = { noRoot, noRoot, NULL, 0, 0, force, this };
+       sh.getEntity = ncXmlGetEntity;
+       sh.startElement = ncXmlStartElement;
+       sh.endElement = ncXmlEndElement;
+
+       lockFile(NC_L_RW);
+       cdir = rdir;
+       int ret = ncXmlSAXParseFile(&sh, &state, filename);
+       cdir = rdir;
+       unLockFile();
+
+       return ret < 0 ? NC_ERR_NVAL : NC_ERR_OK;
+#endif /* HAVE_LIBXML2 */
+}
+
diff --git a/lib/base/object.h b/lib/base/object.h
new file mode 100644 (file)
index 0000000..744bff1
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __base_object_h
+#define __base_object_h
+
+#include <assert.h>
+
+// #define OBJECT_DEBUG
+
+#include <lib/base/smartptr.h>
+#ifdef OBJECT_DEBUG
+#include <lib/base/eerror.h>
+#endif
+
+typedef int RESULT;
+
+class iObject
+{
+public:
+       virtual void AddRef()=0;
+       virtual void Release()=0;
+};
+
+#define DECLARE_REF private: int ref; public: void AddRef(); void Release();
+#ifdef OBJECT_DEBUG
+extern int object_total_remaining;
+#define DEFINE_REF(c) void c::AddRef() { ++object_total_remaining; ++ref; eDebug("OBJECT_DEBUG " #c "+%p now %d", this, ref); } void c::Release() { --object_total_remaining; eDebug("OBJECT_DEBUG " #c "-%p now %d", this, ref-1); if (!--ref) delete this; }
+#else
+#define DEFINE_REF(c) void c::AddRef() { ++ref; } void c::Release() { if (!--ref) delete this; }
+#endif
+
+#endif
diff --git a/lib/base/ringbuffer.h b/lib/base/ringbuffer.h
new file mode 100644 (file)
index 0000000..f2cd905
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef QueueRingBufferH
+#define QueueRingBufferH
+
+template <class T>
+class queueRingBuffer
+{
+       template <class A>
+       struct link
+       {
+               link ( const A &val )
+                       :value(val)
+               {}
+               A value;
+               link *nextLink;
+               link *prevLink;
+       };
+
+       link<T> *lastFilled;
+       link<T> *lastFree;
+       unsigned int max;
+       int count;
+public:
+       queueRingBuffer( unsigned int max );
+       ~queueRingBuffer();
+       int size() { return count; }
+       T& queueRingBuffer::dequeue();
+       T& queueRingBuffer::current();
+       void queueRingBuffer::enqueue( const T &val );
+};
+
+template <class T>
+queueRingBuffer<T>::queueRingBuffer( unsigned int max )
+{
+       // constructor for queues based on ring buffers
+       // create the first link
+       T initialvalue;
+       lastFree = new link<T>( initialvalue );
+       lastFilled = lastFree;
+       // make value point to itself
+       lastFilled->nextLink = lastFilled;
+       lastFilled->prevLink = lastFilled;
+       // now add the remainder of the elements
+       while ( max-- > 0 )
+       {
+               link<T> * newLink = new link<T>( initialvalue );
+               newLink->prevLink = lastFilled;
+               newLink->nextLink = lastFilled->nextLink;
+               lastFilled->nextLink->prevLink = newLink;
+               lastFilled->nextLink = newLink;
+       }
+}
+
+template <class T>
+queueRingBuffer<T>::~queueRingBuffer()
+{
+       // delete all memory associated with ring buffer
+       link<T> * p = lastFree;
+       link<T> * next;
+
+       // walk around the circle deleting nodes
+       while( p->nextLink != lastFree )
+       {
+               next = p->nextLink;
+               delete p;
+               p = next;
+       }
+}
+
+template <class T>
+T& queueRingBuffer<T>::dequeue()
+{
+       // remove element form front of queue
+       // advance last free position
+       lastFree = lastFree->nextLink;
+       count--;
+       // return value stored in last free position
+       return lastFree->value;
+}
+
+template <class T>
+T& queueRingBuffer<T>::current()
+{
+       // return value stored in current
+       return lastFree->nextLink->value;
+}
+
+template <class T>
+void queueRingBuffer<T>::enqueue( const T &val )
+{
+       // add new element to end of queue buffer
+       // first check for potential overflow
+       if( lastFilled->nextLink == lastFree )
+       {
+               eDebug("increase size %d", count);
+               link<T> * newLink = new link<T>( val );
+               newLink->prevLink = lastFilled;
+               newLink->nextLink = lastFilled->nextLink;
+               lastFilled->nextLink->prevLink = newLink;
+               lastFilled->nextLink = newLink;
+       }
+       else
+       {
+               // simply advance the last filled pointer
+               lastFilled = lastFilled->nextLink;
+               lastFilled->value = val;
+       }
+       count++;
+}
+#endif
diff --git a/lib/base/smartptr.cpp b/lib/base/smartptr.cpp
new file mode 100644 (file)
index 0000000..95269d7
--- /dev/null
@@ -0,0 +1,2 @@
+#include "smartptr.h"
+#include <stdio.h>
diff --git a/lib/base/smartptr.h b/lib/base/smartptr.h
new file mode 100644 (file)
index 0000000..029fd1d
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __smartptr_h
+#define __smartptr_h
+
+#include "object.h"
+#include <stdio.h>
+
+template<class T>
+class ePtr
+{
+protected:
+       T *ptr;
+public:
+       T &operator*() { return *ptr; }
+       ePtr(): ptr(0)
+       {
+       }
+       ePtr(T *c): ptr(c)
+       {
+               if (c)
+                       c->AddRef();
+       }
+       ePtr(const ePtr &c)
+       {
+               ptr=c.ptr;
+               if (ptr)
+                       ptr->AddRef();
+       }
+       ePtr &operator=(T *c)
+       {
+               if (ptr)
+                       ptr->Release();
+               ptr=c;
+               if (ptr)
+                       ptr->AddRef();
+               return *this;
+       }
+       
+       ePtr &operator=(ePtr<T> &c)
+       {
+               if (ptr)
+                       ptr->Release();
+               ptr=c.ptr;
+               if (ptr)
+                       ptr->AddRef();
+               return *this;
+       }
+       
+       ~ePtr()
+       {
+               if (ptr)
+                       ptr->Release();
+       }
+       T* &ptrref() { assert(!ptr); return ptr; }
+       T* operator->() { assert(ptr); return ptr; }
+       const T* operator->() const { assert(ptr); return ptr; }
+       operator T*() const { return this->ptr; }
+};
+
+
+#endif
diff --git a/lib/base/thread.cpp b/lib/base/thread.cpp
new file mode 100644 (file)
index 0000000..4cff925
--- /dev/null
@@ -0,0 +1,34 @@
+#include <lib/base/thread.h>
+#include <stdio.h>
+#include <lib/base/eerror.h>
+
+void *eThread::wrapper(void *ptr)
+{
+       ((eThread*)ptr)->thread();
+       pthread_exit(0);
+}
+
+eThread::eThread()
+{
+       alive=0;
+}
+
+void eThread::run()
+{
+       alive=1;
+       pthread_create(&the_thread, 0, wrapper, this);
+}
+
+eThread::~eThread()
+{
+       if (alive)
+               kill();
+}
+
+void eThread::kill()
+{
+       alive=0;
+       eDebug("waiting for thread shutdown");
+       pthread_join(the_thread, 0);
+       eDebug("ok");
+}
diff --git a/lib/base/thread.h b/lib/base/thread.h
new file mode 100644 (file)
index 0000000..56b74be
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __lib_base_thread_h
+#define __lib_base_thread_h
+
+#include <pthread.h>
+
+class eThread
+{
+       pthread_t the_thread;
+       static void *wrapper(void *ptr);
+       int alive;
+public:
+       bool thread_running() { return alive; }
+       eThread();
+       virtual ~eThread();
+       
+       void run();
+
+       virtual void thread()=0;
+       
+       void kill();
+};
+
+#endif
diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am
new file mode 100644 (file)
index 0000000..eff4486
--- /dev/null
@@ -0,0 +1,7 @@
+INCLUDES = \
+       -I$(top_srcdir)/include
+
+noinst_LIBRARIES = libenigma_driver.a
+
+libenigma_driver_a_SOURCES = \
+       rc.cpp rcinput.cpp 
\ No newline at end of file
diff --git a/lib/driver/Makefile.in b/lib/driver/Makefile.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/driver/input_fake.h b/lib/driver/input_fake.h
new file mode 100644 (file)
index 0000000..7aecc9f
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _INPUT_FAKE_H
+#define _INPUT_FAKE_H
+
+#include <linux/input.h>
+
+
+#if !defined(KEY_OK)
+
+/**
+ *  define some additional remote control keys in case they 
+ *  were not already defined above in <linux/input.h>
+ */
+
+#define KEY_OK           0x160
+#define KEY_SELECT       0x161
+#define KEY_GOTO         0x162
+#define KEY_CLEAR        0x163
+#define KEY_POWER2       0x164
+#define KEY_OPTION       0x165
+#define KEY_INFO         0x166
+#define KEY_TIME         0x167
+#define KEY_VENDOR       0x168
+#define KEY_ARCHIVE      0x169
+#define KEY_PROGRAM      0x16a
+#define KEY_CHANNEL      0x16b
+#define KEY_FAVORITES    0x16c
+#define KEY_EPG          0x16d
+#define KEY_PVR          0x16e
+#define KEY_MHP          0x16f
+#define KEY_LANGUAGE     0x170
+#define KEY_TITLE        0x171
+#define KEY_SUBTITLE     0x172
+#define KEY_ANGLE        0x173
+#define KEY_ZOOM         0x174
+#define KEY_MODE         0x175
+#define KEY_KEYBOARD     0x176
+#define KEY_SCREEN       0x177
+#define KEY_PC           0x178
+#define KEY_TV           0x179
+#define KEY_TV2          0x17a
+#define KEY_VCR          0x17b
+#define KEY_VCR2         0x17c
+#define KEY_SAT          0x17d
+#define KEY_SAT2         0x17e
+#define KEY_CD           0x17f
+#define KEY_TAPE         0x180
+#define KEY_RADIO        0x181
+#define KEY_TUNER        0x182
+#define KEY_PLAYER       0x183
+#define KEY_TEXT         0x184
+#define KEY_DVD          0x185
+#define KEY_AUX          0x186
+#define KEY_MP3          0x187
+#define KEY_AUDIO        0x188
+#define KEY_VIDEO        0x189
+#define KEY_DIRECTORY    0x18a
+#define KEY_LIST         0x18b
+#define KEY_MEMO         0x18c
+#define KEY_CALENDAR     0x18d
+#define KEY_RED          0x18e
+#define KEY_GREEN        0x18f
+#define KEY_YELLOW       0x190
+#define KEY_BLUE         0x191
+#define KEY_CHANNELUP    0x192
+#define KEY_CHANNELDOWN  0x193
+#define KEY_FIRST        0x194
+#define KEY_LAST         0x195
+#define KEY_AB           0x196
+#define KEY_PLAY         0x197
+#define KEY_RESTART      0x198
+#define KEY_SLOW         0x199
+#define KEY_SHUFFLE      0x19a
+#define KEY_FASTFORWARD  0x19b
+#define KEY_PREVIOUS     0x19c
+#define KEY_NEXT         0x19d
+#define KEY_DIGITS       0x19e
+#define KEY_TEEN         0x19f
+#define KEY_TWEN         0x1a0
+#define KEY_BREAK        0x1a1
+
+
+#endif  /* !defined(KEY_OK)  */
+#endif  /* _INPUT_FAKE_H */
+
diff --git a/lib/driver/rc.cpp b/lib/driver/rc.cpp
new file mode 100644 (file)
index 0000000..790c5f6
--- /dev/null
@@ -0,0 +1,245 @@
+#include <lib/driver/rc.h>
+
+#include <asm/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/input.h>
+
+#include <lib/base/init.h>
+#include <lib/base/init_num.h>
+#include <lib/base/econfig.h>
+#include <lib/base/eerror.h>
+
+/*
+ *  note on the enigma input layer:
+ *  the enigma input layer (rc*) supports n different devices which
+ *  all have completely different interfaces, mapped down to 32bit + 
+ *  make/break/release codes mapped down (via xml files) to "actions".
+ *  this was necessary to support multiple remote controls with proprietary
+ *  interfaces. now everybody is using input devices, and thus adding
+ *  another input layer seems to be a bit overkill. BUT:
+ *  image a remote control with two hundred buttons. each and every function
+ *  in enigma can be bound to a button. no need to use them twice. 
+ *  for example, you would have KEY_MENU assigned to a menu for setup etc.,
+ *  but no audio and video settings, since you have special keys for that,
+ *  and you don't want to display a big menu with entries that are available
+ *  with another single key.
+ *  then image a remote control with ten buttons. do you really want to waste
+ *  KEY_MENU for a simple menu? you need the audio/video settings there too.
+ *  take this just as a (bad) example. another (better) example might be front-
+ *  button-keys. usually you have KEY_UP, KEY_DOWN, KEY_POWER. you don't want
+ *  them to behave like the remote-control-KEY_UP, KEY_DOWN and KEY_POWER,
+ *  don't you? 
+ *  so here we can map same keys of different input devices to different 
+ *  actions. have fun.
+ */
+
+int eRCDevice::getKeyCompatibleCode(const eRCKey &) const
+{
+       return -1;
+}
+
+eRCDevice::eRCDevice(eString id, eRCDriver *driver): driver(driver), id(id)
+{
+       input=driver->getInput();
+       driver->addCodeListener(this);
+       eRCInput::getInstance()->addDevice(id, this);
+}
+
+eRCDevice::~eRCDevice()
+{
+       driver->removeCodeListener(this);
+       eRCInput::getInstance()->removeDevice(id.c_str());
+}
+
+eRCDriver::eRCDriver(eRCInput *input): input(input), enabled(1)
+{
+}
+
+eRCDriver::~eRCDriver()
+{
+       for (std::list<eRCDevice*>::iterator i=listeners.begin(); i!=listeners.end(); ++i)
+               delete *i;
+}
+
+void eRCShortDriver::keyPressed(int)
+{
+       __u16 rccode;
+       while (1)
+       {
+               if (read(handle, &rccode, 2)!=2)
+                       break;
+               if (enabled && !input->islocked())
+                       for (std::list<eRCDevice*>::iterator i(listeners.begin()); i!=listeners.end(); ++i)
+                               (*i)->handleCode(rccode);
+       }
+}
+
+eRCShortDriver::eRCShortDriver(const char *filename): eRCDriver(eRCInput::getInstance())
+{
+       handle=open(filename, O_RDONLY|O_NONBLOCK);
+       if (handle<0)
+       {
+               eDebug("failed to open %s", filename);
+               sn=0;
+       } else
+       {
+               sn=new eSocketNotifier(eApp, handle, eSocketNotifier::Read);
+               CONNECT(sn->activated, eRCShortDriver::keyPressed);
+               eRCInput::getInstance()->setFile(handle);
+       }
+}
+
+eRCShortDriver::~eRCShortDriver()
+{
+       if (handle>=0)
+               close(handle);
+       if (sn)
+               delete sn;
+}
+
+void eRCInputEventDriver::keyPressed(int)
+{
+       struct input_event ev;
+       while (1)
+       {
+               if (read(handle, &ev, sizeof(struct input_event))!=sizeof(struct input_event))
+                       break;
+               if (enabled && !input->islocked())
+                       for (std::list<eRCDevice*>::iterator i(listeners.begin()); i!=listeners.end(); ++i)
+                               (*i)->handleCode((int)&ev);
+       }
+}
+
+eRCInputEventDriver::eRCInputEventDriver(const char *filename): eRCDriver(eRCInput::getInstance())
+{
+       handle=open(filename, O_RDONLY|O_NONBLOCK);
+       if (handle<0)
+       {
+               eDebug("failed to open %s", filename);
+               sn=0;
+       } else
+       {
+               sn=new eSocketNotifier(eApp, handle, eSocketNotifier::Read);
+               CONNECT(sn->activated, eRCInputEventDriver::keyPressed);
+               eRCInput::getInstance()->setFile(handle);
+       }
+}
+
+eString eRCInputEventDriver::getDeviceName()
+{
+       char name[128]="";
+       if (handle >= 0)
+               ::ioctl(handle, EVIOCGNAME(128), name);
+       return name;
+}
+
+eRCInputEventDriver::~eRCInputEventDriver()
+{
+       if (handle>=0)
+               close(handle);
+       if (sn)
+               delete sn;
+}
+
+eRCConfig::eRCConfig()
+{
+       reload();
+}
+
+eRCConfig::~eRCConfig()
+{
+       save();
+}
+
+void eRCConfig::set( int delay, int repeat )
+{
+       rdelay = delay;
+       rrate = repeat;
+}
+
+void eRCConfig::reload()
+{
+       rdelay=500;
+       rrate=100;
+       if ( eConfig::getInstance()->getKey("/ezap/rc/repeatRate", rrate) )
+               save();
+       eConfig::getInstance()->getKey("/ezap/rc/repeatDelay", rdelay);
+}
+
+void eRCConfig::save()
+{
+       eConfig::getInstance()->setKey("/ezap/rc/repeatRate", rrate);
+       eConfig::getInstance()->setKey("/ezap/rc/repeatDelay", rdelay);
+}
+
+eRCInput *eRCInput::instance;
+
+eRCInput::eRCInput()
+{
+       ASSERT( !instance);
+       instance=this;
+       handle = -1;
+       locked = 0;
+}
+
+eRCInput::~eRCInput()
+{
+}
+
+void eRCInput::close()
+{
+}
+
+bool eRCInput::open()
+{
+       return false;
+}
+
+int eRCInput::lock()
+{
+       locked=1;
+       return handle;
+}
+
+void eRCInput::unlock()
+{
+       if (locked)
+               locked=0;
+}
+
+void eRCInput::setFile(int newh)
+{
+       handle=newh;
+}
+
+void eRCInput::addDevice(const eString &id, eRCDevice *dev)
+{
+       devices.insert(std::pair<eString,eRCDevice*>(id, dev));
+}
+
+void eRCInput::removeDevice(const eString &id)
+{
+       devices.erase(id);
+}
+
+eRCDevice *eRCInput::getDevice(const eString &id)
+{
+       std::map<eString,eRCDevice*>::iterator i=devices.find(id);
+       if (i == devices.end())
+       {
+               eDebug("failed, possible choices are:");
+               for (std::map<eString,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i) 
+                       eDebug("%s", i->first.c_str());
+               return 0;
+       }
+       return i->second;
+}
+
+std::map<eString,eRCDevice*,eRCInput::lstr> &eRCInput::getDevices()
+{
+       return devices;
+}
+
+eAutoInitP0<eRCInput> init_rcinput(eAutoInitNumbers::rc, "RC Input layer");
diff --git a/lib/driver/rc.h b/lib/driver/rc.h
new file mode 100644 (file)
index 0000000..557be5e
--- /dev/null
@@ -0,0 +1,226 @@
+#ifndef __rc_h
+#define __rc_h
+
+#include <list>
+#include <map>
+
+#include <lib/base/ebase.h>
+#include <libsig_comp.h>
+#include <lib/base/estring.h>
+
+class eRCInput;
+class eRCDriver;
+class eRCKey;
+
+/**
+ * \brief A remote control.
+ *
+ * Handles one remote control. Gets codes from a \ref eRCDriver. Produces events in \ref eRCInput.
+ */
+class eRCDevice: public Object
+{
+protected:
+       eRCInput *input;
+       eRCDriver *driver;
+       eString id;
+public:
+       /**
+        * \brief Constructs a new remote control.
+        *
+        * \param id The identifier of the RC, for use in settings.
+        * \param input The \ref eRCDriver where this remote gets its codes from.
+        */
+       eRCDevice(eString id, eRCDriver *input);
+       ~eRCDevice();
+       /**
+        * \brief Handles a device specific code.
+        *
+        * Generates events in \ref eRCInput. code is highly device- and driver dependant.
+        * For Example, it might be 16bit codes with one bit make/break or special codes
+        * for repeat.
+        */
+       virtual void handleCode(int code)=0;
+       /**
+        * \brief Get user readable description.
+        * \result The description.
+        */
+       virtual const char *getDescription() const=0;
+       const eString getIdentifier() const { return id; }
+       /**
+        * \brief Get a description for a specific key.
+        * \param key The key to get the description for.
+        * \result User readable description of given key.
+        */
+       virtual const char *getKeyDescription(const eRCKey &key) const=0;
+       /**
+        * \brief Get a dbox2-compatible keycode.
+        *
+        * THIS IS DEPRECATED! DON'T USE IT UNLESS YOU NEED IT!
+        * \param key The key to get the compatible code for.
+        * \result The dbox2-compatible code. (new RC as defined in enum).
+        */
+       virtual int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+/**
+ * Receives codes from one or more remote controls.
+ */
+class eRCDriver: public Object
+{
+protected:
+       std::list<eRCDevice*> listeners;
+       eRCInput *input;
+       int enabled;
+public:
+       /**
+        * \brief Constructs a driver.
+        *
+        * \param input The RCInput to bind this driver to.
+        */
+       eRCDriver(eRCInput *input);
+       /**
+        * \brief Get pointer to key-consumer.
+        */
+       eRCInput *getInput() const { return input; }
+       /**
+        * \brief Adds a code lister
+        */
+       void addCodeListener(eRCDevice *dev)
+       {
+               listeners.push_back(dev);
+       }
+       void removeCodeListener(eRCDevice *dev)
+       {
+               listeners.remove(dev);
+       }
+       ~eRCDriver();
+       
+       void enable(int en) { enabled=en; }
+};
+
+class eRCShortDriver: public eRCDriver
+{
+protected:
+       int handle;
+       eSocketNotifier *sn;
+       void keyPressed(int);
+public:
+       eRCShortDriver(const char *filename);
+       ~eRCShortDriver();
+};
+
+class eRCInputEventDriver: public eRCDriver
+{
+protected:
+       int handle;
+       eSocketNotifier *sn;
+       void keyPressed(int);
+public:
+       eString getDeviceName();
+       eRCInputEventDriver(const char *filename);
+       ~eRCInputEventDriver();
+};
+
+class eRCKey
+{
+public:
+       eRCDevice *producer;
+       int code, flags;
+
+       eRCKey(eRCDevice *producer, int code, int flags): 
+               producer(producer), code(code), flags(flags)
+       {
+       }
+       enum
+       {
+               flagBreak=1,
+               flagRepeat=2
+       };
+       
+       bool operator<(const eRCKey &r) const
+       {
+               if (r.producer == producer)
+               {
+                       if (r.code == code)
+                       {
+                               if (r.flags < flags)
+                                       return 1;
+                               else
+                                       return 0;
+                       } else if (r.code < code)
+                               return 1;
+                       else
+                               return 0;
+               } else if (r.producer < producer)
+                       return 1;
+               else
+                       return 0;
+       }
+};
+
+class eRCConfig
+{
+public:
+       eRCConfig();
+       ~eRCConfig();
+       void reload();
+       void save();
+       void set(int delay, int repeat);
+       int rdelay, // keypress delay after first keypress to begin of repeat (in ms)
+               rrate;          // repeat rate (in ms)
+};
+
+class eRCInput: public Object
+{
+       int locked;     
+       int handle;
+       static eRCInput *instance;
+
+public:
+       struct lstr
+       {
+               bool operator()(const eString &a, const eString &b) const
+               {
+                       return a<b;
+               }
+       };
+protected:
+       std::map<eString,eRCDevice*,lstr> devices;
+public:
+       Signal1<void, const eRCKey&> keyEvent;
+       enum
+       {
+               RC_0=0, RC_1=0x1, RC_2=0x2, RC_3=0x3, RC_4=0x4, RC_5=0x5, RC_6=0x6, RC_7=0x7,
+               RC_8=0x8, RC_9=0x9,
+               RC_RIGHT=10, RC_LEFT=11, RC_UP=12, RC_DOWN=13, RC_OK=14, RC_MUTE=15,
+               RC_STANDBY=16, RC_GREEN=17, RC_YELLOW=18, RC_RED=19, RC_BLUE=20, RC_PLUS=21, RC_MINUS=22,
+               RC_HELP=23, RC_DBOX=24,
+               RC_UP_LEFT=27, RC_UP_RIGHT=28, RC_DOWN_LEFT=29, RC_DOWN_RIGHT=30, RC_HOME=31
+       };
+       eRCInput();
+       ~eRCInput();
+       
+       int lock();
+       void unlock();
+       int islocked() { return locked; }
+       void close();
+       bool open();
+
+       void setFile(int handle);
+
+       void keyPressed(const eRCKey &key)
+       {
+               /*emit*/ keyEvent(key);
+       }
+       
+       void addDevice(const eString &id, eRCDevice *dev);
+       void removeDevice(const eString &id);
+       eRCDevice *getDevice(const eString &id);
+       std::map<eString,eRCDevice*,lstr> &getDevices();
+       
+       static eRCInput *getInstance() { return instance; }
+       
+       eRCConfig config;
+};
+
+#endif
diff --git a/lib/driver/rcdbox.h b/lib/driver/rcdbox.h
new file mode 100644 (file)
index 0000000..bd361f6
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef DISABLE_DBOX_RC
+
+#ifndef __rcdbox_h
+#define __rcdbox_h
+
+#include <lib/driver/rc.h>
+
+class eRCDeviceDBoxOld: public eRCDevice
+{
+       int last, ccode;
+       eTimer timeout, repeattimer;
+private:
+       void timeOut();
+       void repeat();
+public:
+       void handleCode(int code);
+       eRCDeviceDBoxOld(eRCDriver *driver);
+       const char *getDescription() const;
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+class eRCDeviceDBoxNew: public eRCDevice
+{
+       int last, ccode;
+       eTimer timeout, repeattimer;
+private:
+       void timeOut();
+       void repeat();
+public:
+       void handleCode(int code);
+       eRCDeviceDBoxNew(eRCDriver *driver);
+       const char *getDescription() const;
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+class eRCDeviceDBoxButton: public eRCDevice
+{
+       int last;
+       eTimer repeattimer;
+private:
+       void repeat();
+public:
+       void handleCode(int code);
+       eRCDeviceDBoxButton(eRCDriver *driver);
+       const char *getDescription() const;
+
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+class eRCDBoxDriver: public eRCShortDriver
+{
+public:
+       eRCDBoxDriver();
+};
+
+#endif
+
+#endif // DISABLE_DBOX_RC
diff --git a/lib/driver/rcdreambox2.h b/lib/driver/rcdreambox2.h
new file mode 100644 (file)
index 0000000..e77beb4
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef DISABLE_DREAMBOX_RC
+
+#ifndef __rcdreambox2_h
+#define __rcdreambox2_h
+
+#include <lib/driver/rc.h>
+
+class eRCDeviceDreambox2: public eRCDevice
+{
+       int last, ccode;
+       eTimer timeout, repeattimer;
+private:
+       void timeOut();
+       void repeat();
+public:
+       void handleCode(int code);
+       eRCDeviceDreambox2(eRCDriver *driver);
+       const char *getDescription() const;
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+class eRCDreamboxDriver2: public eRCShortDriver
+{
+public:
+       eRCDreamboxDriver2();
+};
+
+class eRCDeviceDreamboxButton: public eRCDevice
+{
+       int last;
+       eTimer repeattimer;
+private:
+       void repeat();
+public:
+       void handleCode(int code);
+       eRCDeviceDreamboxButton(eRCDriver *driver);
+       const char *getDescription() const;
+
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+class eRCDreamboxButtonDriver: public eRCShortDriver
+{
+public:
+       eRCDreamboxButtonDriver();
+};
+#endif
+
+#endif // DISABLE_DREAMBOX_RC
diff --git a/lib/driver/rcinput.cpp b/lib/driver/rcinput.cpp
new file mode 100644 (file)
index 0000000..041330a
--- /dev/null
@@ -0,0 +1,126 @@
+#include <lib/driver/rcinput.h>
+
+#include <sys/ioctl.h>
+#include <linux/input.h>
+#include <sys/stat.h>
+
+#include <lib/base/ebase.h>
+#include <lib/base/init.h>
+#include <lib/base/init_num.h>
+#include <lib/driver/input_fake.h>
+
+void eRCDeviceInputDev::handleCode(int rccode)
+{
+       struct input_event *ev = (struct input_event *)rccode;
+       if (ev->type!=EV_KEY)
+               return;
+       eDebug("%x %x %x", ev->value, ev->code, ev->type);
+       switch (ev->value)
+       {
+       case 0:
+               /*emit*/ input->keyPressed(eRCKey(this, ev->code, eRCKey::flagBreak));
+               break;
+       case 1:
+               /*emit*/ input->keyPressed(eRCKey(this, ev->code, 0));
+               break;
+       case 2:
+               /*emit*/ input->keyPressed(eRCKey(this, ev->code, eRCKey::flagRepeat));
+               break;
+       }
+}
+
+eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver): eRCDevice(driver->getDeviceName(), driver)
+{
+}
+
+const char *eRCDeviceInputDev::getDescription() const
+{
+       return id.c_str();
+}
+
+const char *eRCDeviceInputDev::getKeyDescription(const eRCKey &key) const
+{
+       switch (key.code)
+       {
+       case KEY_0: return "0";
+       case KEY_1: return "1";
+       case KEY_2: return "2";
+       case KEY_3: return "3";
+       case KEY_4: return "4";
+       case KEY_5: return "5";
+       case KEY_6: return "6";
+       case KEY_7: return "7";
+       case KEY_8: return "8";
+       case KEY_9: return "9";
+       case KEY_RIGHT: return "rechts";
+       case KEY_LEFT: return "links";
+       case KEY_UP: return "oben";
+       case KEY_DOWN: return "unten";
+       case KEY_OK: return "ok";
+       case KEY_MUTE: return "mute";
+       case KEY_POWER: return "power";
+       case KEY_GREEN: return "gruen";
+       case KEY_YELLOW: return "gelb";
+       case KEY_RED: return "rot";
+       case KEY_BLUE: return "blau";
+       case KEY_VOLUMEUP: return "Lautstaerke plus";
+       case KEY_VOLUMEDOWN: return "Lautstaerke minus";
+       case KEY_HELP: return "?";
+       case KEY_SETUP: return "d-Box";
+#if 0
+       case KEY_TOPLEFT: return "oben links";
+       case KEY_TOPRIGHT: return "oben rechts";
+       case KEY_BOTTOMLEFT: return "unten links";
+       case KEY_BOTTOMRIGHT: return "unten rechts";
+#endif
+       case KEY_HOME: return "home";
+       default: return 0;
+       }
+}
+
+int eRCDeviceInputDev::getKeyCompatibleCode(const eRCKey &key) const
+{
+       switch (key.code)
+       {
+               case KEY_0: return eRCInput::RC_0;
+               case KEY_1: return eRCInput::RC_1;
+               case KEY_2: return eRCInput::RC_2;
+               case KEY_3: return eRCInput::RC_3;
+               case KEY_4: return eRCInput::RC_4;
+               case KEY_5: return eRCInput::RC_5;
+               case KEY_6: return eRCInput::RC_6;
+               case KEY_7: return eRCInput::RC_7;
+               case KEY_8: return eRCInput::RC_8;
+               case KEY_9: return eRCInput::RC_9;
+               case KEY_RIGHT: return eRCInput::RC_RIGHT;
+               case KEY_LEFT: return eRCInput::RC_LEFT;
+               case KEY_UP: return eRCInput::RC_UP;
+               case KEY_DOWN: return eRCInput::RC_DOWN;
+               case KEY_OK: return eRCInput::RC_OK;
+               case KEY_MUTE: return eRCInput::RC_MUTE;
+               case KEY_POWER: return eRCInput::RC_STANDBY;
+               case KEY_GREEN: return eRCInput::RC_GREEN;
+               case KEY_YELLOW: return eRCInput::RC_YELLOW;
+               case KEY_RED: return eRCInput::RC_RED;
+               case KEY_VOLUMEUP: return eRCInput::RC_PLUS;
+               case KEY_BLUE: return eRCInput::RC_BLUE;
+               case KEY_VOLUMEDOWN: return eRCInput::RC_MINUS;
+               case KEY_HELP: return eRCInput::RC_HELP;
+               case KEY_SETUP: return eRCInput::RC_DBOX;
+               case KEY_HOME: return eRCInput::RC_HOME;
+       }
+       return -1;
+}
+
+
+class eInputDeviceInit
+{
+       eRCInputEventDriver driver;
+       eRCDeviceInputDev deviceInputDev;
+public:
+       eInputDeviceInit(): driver("/dev/input/event0"), deviceInputDev(&driver)
+       {
+       }
+};
+
+eAutoInitP0<eInputDeviceInit> init_rcinputdev(eAutoInitNumbers::rc+1, "input device driver");
diff --git a/lib/driver/rcinput.h b/lib/driver/rcinput.h
new file mode 100644 (file)
index 0000000..c13eafb
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __rcdbox_h
+#define __rcdbox_h
+
+#include <lib/driver/rc.h>
+
+class eRCDeviceInputDev: public eRCDevice
+{
+public:
+       void handleCode(int code);
+       eRCDeviceInputDev(eRCInputEventDriver *driver);
+       const char *getDescription() const;
+
+       const char *getKeyDescription(const eRCKey &key) const;
+       int getKeyCompatibleCode(const eRCKey &key) const;
+};
+
+#endif
diff --git a/lib/driver/rfmod.h b/lib/driver/rfmod.h
new file mode 100644 (file)
index 0000000..e3acc47
--- /dev/null