Initial import.
38
deluge/glade/aboutdialog.glade
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.1.5 on Thu Feb 22 19:13:48 2007 by zach@notapowerbook-->
|
||||
<glade-interface>
|
||||
<widget class="GtkAboutDialog" id="aboutdialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="has_separator">False</property>
|
||||
<property name="website"></property>
|
||||
<property name="authors"></property>
|
||||
<property name="translator-credits"></property>
|
||||
<property name="documenters"></property>
|
||||
<property name="artists"></property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
1140
deluge/glade/delugegtk.glade
Normal file
406
deluge/glade/dgtkpopups.glade
Normal file
|
@ -0,0 +1,406 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.2.2 on Wed Jun 20 16:04:00 2007 by andrew@fractal-->
|
||||
<glade-interface>
|
||||
<widget class="GtkMenu" id="torrent_popup">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Size</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="size_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Status</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="status_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Seeders</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="seeders_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Peers</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="peers_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Download Speed</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="dl_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Upload Speed</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="ul_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem7">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Time Remaining</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="eta_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="menuitem8">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Share Ratio</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="share_toggle"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkDialog" id="remove_torrent_dlg">
|
||||
<property name="title" translatable="yes">Remove Torrent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-dialog-warning</property>
|
||||
<property name="icon_size">6</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes"><span size="large"><b>Are you sure you want to remove the selected torrent(s) from Deluge?</b></span></property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">20</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="data_also">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Delete downloaded files</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">20</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="torrent_also">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Delete .torrent file</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="warning">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area3">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-no</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-yes</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkMenu" id="tray_menu">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menuitem10">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Show/Hide</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="show_hide_window"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem9">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Add a Torrent...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="add_torrent"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem11">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Clear Finished</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="clear_finished"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-clear</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem12">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-preferences</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="preferences"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem13">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Plugins</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="plugins"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem14">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="quit"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkDialog" id="rate_dialog">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="window_position">GTK_WIN_POS_MOUSE</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="decorated">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Rate:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="spin_rate">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="is_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="activates_default">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="adjustment">0 -1 10000 1 10 10</property>
|
||||
<property name="numeric">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
120
deluge/glade/edit_trackers.glade
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.2.2 on Wed Jun 27 17:27:11 2007 by markybob@peg-->
|
||||
<glade-interface>
|
||||
<widget class="GtkWindow" id="edittrackers">
|
||||
<property name="width_request">300</property>
|
||||
<property name="height_request">200</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="title" translatable="yes">Edit Trackers</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="height_request">36</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Tracker Editing</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="txt_tracker_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkAspectFrame" id="aspectframe1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="ratio">1</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="cancel_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="ok_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAspectFrame" id="aspectframe2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="ratio">1</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
100
deluge/glade/file_tab_menu.glade
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkMenu" id="file_tab_menu">
|
||||
<property name="visible">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="select_all">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Select All</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="select_all" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image22">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="unselect_all">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Unselect All</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="unselect_all" last_modification_time="Mon, 11 Jun 2007 13:16:59 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image23">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-file</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separator">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="check_selected">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Check Selected</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="check_selected" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image24">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-ok</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="uncheck_selected">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Uncheck Selected</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="uncheck_selected" last_modification_time="Mon, 11 Jun 2007 12:54:52 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image25">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-remove</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
114
deluge/glade/plugin_dialog.glade
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="plugin_dialog">
|
||||
<property name="width_request">480</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Plugin Manager</property>
|
||||
<property name="default_width">583</property>
|
||||
<property name="default_height">431</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkNotebook" id="pref_notebook1">
|
||||
<property name="visible">True</property>
|
||||
<property name="show_tabs">False</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="plugin_view">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="plugin_text">
|
||||
<property name="visible">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="plugin_conf">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="label">gtk-preferences</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="plugin_pref"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label34">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Plugins</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button10">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
1461
deluge/glade/preferences_dialog.glade
Normal file
165
deluge/glade/torrent_menu.glade
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkMenu" id="torrent_menu">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menu_pause">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-media-pause</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="start_pause"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Update Tracker</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="update_tracker"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem13">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Edit Trackers</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="edit_trackers"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separator">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Remove Torrent</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="remove_torrent"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image9">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-remove</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separator">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Queue</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menu1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Top</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="queue_top"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image10">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-goto-top</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Up</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="queue_up"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-go-up</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem7">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Down</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="queue_down"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-go-down</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menuitem8">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Bottom</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="queue_bottom"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-goto-bottom</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image11">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-sort-ascending</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
158
deluge/glade/tray_menu.glade
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkMenu" id="tray_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="show_hide_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Show Deluge</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="show_hide_window_toggled"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="add_torrent">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Add Torrent</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="add_torrent"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="clear_finished">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Clear Finished</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="clear_finished"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-clear</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="download_limit">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Download Limit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menu1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="download-limit-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="upload_limit">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Upload Limit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="upload-limit-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="preferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-preferences</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="preferences"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="plugins">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Plu_gins</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="plugins"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-disconnect</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="quit">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="quit"/>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-quit</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
BIN
deluge/pixmaps/deluge-about.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
deluge/pixmaps/deluge128.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
deluge/pixmaps/deluge192.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
deluge/pixmaps/deluge22.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
deluge/pixmaps/deluge256.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
deluge/pixmaps/deluge32.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
deluge/pixmaps/downloading16.png
Normal file
After Width: | Height: | Size: 662 B |
BIN
deluge/pixmaps/inactive16.png
Normal file
After Width: | Height: | Size: 588 B |
BIN
deluge/pixmaps/seeding16.png
Normal file
After Width: | Height: | Size: 612 B |
13
deluge/share/applications/deluge.desktop
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Encoding=UTF-8
|
||||
Name=Deluge BitTorrent Client
|
||||
Comment=Bittorrent client written in PyGTK
|
||||
Exec=deluge
|
||||
Icon=deluge.xpm
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Application;Network
|
||||
StartupNotify=true
|
||||
MimeType=application/x-bittorrent;
|
||||
GenericName=
|
415
deluge/share/pixmaps/deluge.xpm
Normal file
|
@ -0,0 +1,415 @@
|
|||
/* XPM */
|
||||
static char * deluge_torrent_xpm[] = {
|
||||
"32 32 380 2",
|
||||
" c None",
|
||||
". c #8893A8",
|
||||
"+ c #8994A8",
|
||||
"@ c #B0B7C5",
|
||||
"# c #919BAE",
|
||||
"$ c #737F98",
|
||||
"% c #A3ABBB",
|
||||
"& c #8E98AD",
|
||||
"* c #AEB5C4",
|
||||
"= c #858FA5",
|
||||
"- c #5E6D89",
|
||||
"; c #929CB0",
|
||||
"> c #8794A9",
|
||||
", c #8592AA",
|
||||
"' c #919FB5",
|
||||
") c #A5B0C3",
|
||||
"! c #7688A4",
|
||||
"~ c #7687A1",
|
||||
"{ c #8A99B1",
|
||||
"] c #768AA7",
|
||||
"^ c #7E92AE",
|
||||
"/ c #8397B3",
|
||||
"( c #92A4BD",
|
||||
"_ c #96A8C0",
|
||||
": c #5B7295",
|
||||
"< c #8B9DB7",
|
||||
"[ c #6A83A4",
|
||||
"} c #728BAD",
|
||||
"| c #7791B3",
|
||||
"1 c #7B95B6",
|
||||
"2 c #7C96B8",
|
||||
"3 c #95ABC6",
|
||||
"4 c #829CBC",
|
||||
"5 c #45618C",
|
||||
"6 c #7F96B3",
|
||||
"7 c #6483A9",
|
||||
"8 c #6384AC",
|
||||
"9 c #6B8BB3",
|
||||
"0 c #7091B8",
|
||||
"a c #7495BC",
|
||||
"b c #7596BD",
|
||||
"c c #7496BD",
|
||||
"d c #95AECC",
|
||||
"e c #6F91B9",
|
||||
"f c #6081A9",
|
||||
"g c #3C6292",
|
||||
"h c #365989",
|
||||
"i c #4B6B97",
|
||||
"j c #5676A1",
|
||||
"k c #5F81AB",
|
||||
"l c #6E93BF",
|
||||
"m c #7097C2",
|
||||
"n c #7297C3",
|
||||
"o c #8FADCE",
|
||||
"p c #618AB7",
|
||||
"q c #476D9D",
|
||||
"r c #5A779F",
|
||||
"s c #1B4075",
|
||||
"t c #1F4377",
|
||||
"u c #365785",
|
||||
"v c #4A6791",
|
||||
"w c #4D6B94",
|
||||
"x c #5D80AA",
|
||||
"y c #6C93BF",
|
||||
"z c #779DC6",
|
||||
"A c #84A6CB",
|
||||
"B c #5382B6",
|
||||
"C c #3A659A",
|
||||
"D c #5C789F",
|
||||
"E c #224579",
|
||||
"F c #1E4277",
|
||||
"G c #274A7C",
|
||||
"H c #2E4F7F",
|
||||
"I c #335483",
|
||||
"J c #44628D",
|
||||
"K c #557197",
|
||||
"L c #526E95",
|
||||
"M c #506F99",
|
||||
"N c #668FBD",
|
||||
"O c #7FA3CA",
|
||||
"P c #7299C4",
|
||||
"Q c #36639A",
|
||||
"R c #4F6D97",
|
||||
"S c #345484",
|
||||
"T c #305181",
|
||||
"U c #42618A",
|
||||
"V c #4E6992",
|
||||
"W c #4A678F",
|
||||
"X c #4B6992",
|
||||
"Y c #4B6994",
|
||||
"Z c #5F7A9E",
|
||||
"` c #5E779C",
|
||||
" . c #597398",
|
||||
".. c #527099",
|
||||
"+. c #618ABA",
|
||||
"@. c #84A6CD",
|
||||
"#. c #5D89BB",
|
||||
"$. c #375A89",
|
||||
"%. c #4C6992",
|
||||
"&. c #3A5986",
|
||||
"*. c #536E94",
|
||||
"=. c #577197",
|
||||
"-. c #6F92BB",
|
||||
";. c #759ECA",
|
||||
">. c #739CCA",
|
||||
",. c #759DC9",
|
||||
"'. c #6880A4",
|
||||
"). c #5C7699",
|
||||
"!. c #4F6F98",
|
||||
"~. c #618DBD",
|
||||
"{. c #81A4CA",
|
||||
"]. c #4B7CB3",
|
||||
"^. c #274F84",
|
||||
"/. c #5A759B",
|
||||
"(. c #375784",
|
||||
"_. c #577196",
|
||||
":. c #5A7498",
|
||||
"<. c #6F89AB",
|
||||
"[. c #8BADD1",
|
||||
"}. c #7EA5D0",
|
||||
"|. c #7FA6D0",
|
||||
"1. c #7CA4CF",
|
||||
"2. c #7CA4CE",
|
||||
"3. c #789FC7",
|
||||
"4. c #6984A7",
|
||||
"5. c #5A7398",
|
||||
"6. c #5076A5",
|
||||
"7. c #6791C0",
|
||||
"8. c #7198C3",
|
||||
"9. c #2D5081",
|
||||
"0. c #25477A",
|
||||
"a. c #4C6890",
|
||||
"b. c #627A9D",
|
||||
"c. c #657DA1",
|
||||
"d. c #A0BBD7",
|
||||
"e. c #89AED6",
|
||||
"f. c #8BAFD7",
|
||||
"g. c #8BB0D7",
|
||||
"h. c #8AAED6",
|
||||
"i. c #86ACD4",
|
||||
"j. c #82A8D2",
|
||||
"k. c #7CA3CF",
|
||||
"l. c #749DC8",
|
||||
"m. c #6984A6",
|
||||
"n. c #567298",
|
||||
"o. c #5786BA",
|
||||
"p. c #779CC6",
|
||||
"q. c #5583B7",
|
||||
"r. c #295086",
|
||||
"s. c #2C4E7F",
|
||||
"t. c #345483",
|
||||
"u. c #5B7498",
|
||||
"v. c #5D7699",
|
||||
"w. c #93AAC4",
|
||||
"x. c #9EBDDD",
|
||||
"y. c #96B8DD",
|
||||
"z. c #97B9DE",
|
||||
"A. c #94B7DC",
|
||||
"B. c #90B3DA",
|
||||
"C. c #8AAFD6",
|
||||
"D. c #83A9D2",
|
||||
"E. c #7AA2CE",
|
||||
"F. c #6F95BF",
|
||||
"G. c #667E9F",
|
||||
"H. c #577FAF",
|
||||
"I. c #5585B8",
|
||||
"J. c #759AC5",
|
||||
"K. c #3F6FA7",
|
||||
"L. c #254A80",
|
||||
"M. c #5C769C",
|
||||
"N. c #3C5B87",
|
||||
"O. c #60789C",
|
||||
"P. c #B0C3D8",
|
||||
"Q. c #A1C0E3",
|
||||
"R. c #A3C2E4",
|
||||
"S. c #A3C3E5",
|
||||
"T. c #A2C2E4",
|
||||
"U. c #9EBFE2",
|
||||
"V. c #98BADE",
|
||||
"W. c #91B4DA",
|
||||
"X. c #88AED6",
|
||||
"Y. c #759ECB",
|
||||
"Z. c #6885AD",
|
||||
"`. c #5780B0",
|
||||
" + c #5383B8",
|
||||
".+ c #7299C3",
|
||||
"++ c #4675AB",
|
||||
"@+ c #395A89",
|
||||
"#+ c #46648F",
|
||||
"$+ c #3E5D88",
|
||||
"%+ c #617A9C",
|
||||
"&+ c #637B9D",
|
||||
"*+ c #BFD1E4",
|
||||
"=+ c #ADCBEA",
|
||||
"-+ c #B0CDEB",
|
||||
";+ c #AFCCEB",
|
||||
">+ c #ACCAE9",
|
||||
",+ c #A7C6E6",
|
||||
"'+ c #9FC0E2",
|
||||
")+ c #8DB1D8",
|
||||
"!+ c #82A9D2",
|
||||
"~+ c #77A0CC",
|
||||
"{+ c #6A94C4",
|
||||
"]+ c #5F8DBF",
|
||||
"^+ c #5C89BA",
|
||||
"/+ c #5C85B4",
|
||||
"(+ c #3F5E8B",
|
||||
"_+ c #3B5A86",
|
||||
":+ c #647C9E",
|
||||
"<+ c #61799D",
|
||||
"[+ c #C1D2E4",
|
||||
"}+ c #BBD5F1",
|
||||
"|+ c #BCD6F2",
|
||||
"1+ c #BAD5F1",
|
||||
"2+ c #B5D1EE",
|
||||
"3+ c #AECBEA",
|
||||
"4+ c #A5C4E5",
|
||||
"5+ c #9BBCE0",
|
||||
"6+ c #84AAD3",
|
||||
"7+ c #78A0CC",
|
||||
"8+ c #6B96C6",
|
||||
"9+ c #5F8CBF",
|
||||
"0+ c #5282B8",
|
||||
"a+ c #4F7FB4",
|
||||
"b+ c #668CB7",
|
||||
"c+ c #43618D",
|
||||
"d+ c #325382",
|
||||
"e+ c #5E779B",
|
||||
"f+ c #5F789A",
|
||||
"g+ c #BACADC",
|
||||
"h+ c #C9E0F9",
|
||||
"i+ c #C7DFF8",
|
||||
"j+ c #C3DCF6",
|
||||
"k+ c #BCD7F2",
|
||||
"l+ c #B3CFED",
|
||||
"m+ c #A8C7E7",
|
||||
"n+ c #9DBEE1",
|
||||
"o+ c #6A96C5",
|
||||
"p+ c #5D8BBE",
|
||||
"q+ c #5081B7",
|
||||
"r+ c #497BB2",
|
||||
"s+ c #698DB7",
|
||||
"t+ c #45638E",
|
||||
"u+ c #2E5080",
|
||||
"v+ c #25487B",
|
||||
"w+ c #506B93",
|
||||
"x+ c #647B9E",
|
||||
"y+ c #9DAFC7",
|
||||
"z+ c #D6E9FD",
|
||||
"A+ c #D1E8FE",
|
||||
"B+ c #CAE2FA",
|
||||
"C+ c #C1DAF5",
|
||||
"D+ c #A9C8E8",
|
||||
"E+ c #6894C4",
|
||||
"F+ c #5A89BC",
|
||||
"G+ c #4D7EB5",
|
||||
"H+ c #4577AF",
|
||||
"I+ c #6B8DB5",
|
||||
"J+ c #3B6090",
|
||||
"K+ c #3D5D8A",
|
||||
"L+ c #3C5B89",
|
||||
"M+ c #1D4276",
|
||||
"N+ c #647C9C",
|
||||
"O+ c #657D9E",
|
||||
"P+ c #C2D4E6",
|
||||
"Q+ c #D3E9FF",
|
||||
"R+ c #CEE5FC",
|
||||
"S+ c #C2DBF5",
|
||||
"T+ c #80A7D1",
|
||||
"U+ c #729CC9",
|
||||
"V+ c #6491C2",
|
||||
"W+ c #5686BA",
|
||||
"X+ c #497BB3",
|
||||
"Y+ c #5580B3",
|
||||
"Z+ c #5B7EAA",
|
||||
"`+ c #335686",
|
||||
" @ c #4D6993",
|
||||
".@ c #26497B",
|
||||
"+@ c #4C6990",
|
||||
"@@ c #6B82A2",
|
||||
"#@ c #7D92B0",
|
||||
"$@ c #C1D4E9",
|
||||
"%@ c #C0DAF4",
|
||||
"&@ c #B2CFED",
|
||||
"*@ c #7BA3CE",
|
||||
"=@ c #6F99C7",
|
||||
"-@ c #6390C0",
|
||||
";@ c #5886B9",
|
||||
">@ c #4A7BB2",
|
||||
",@ c #698CB7",
|
||||
"'@ c #4C6F9C",
|
||||
")@ c #284C7F",
|
||||
"!@ c #577299",
|
||||
"~@ c #2F517F",
|
||||
"{@ c #536E93",
|
||||
"]@ c #7086A5",
|
||||
"^@ c #7B8FAC",
|
||||
"/@ c #9FB3CD",
|
||||
"(@ c #B8D2EE",
|
||||
"_@ c #91B5DB",
|
||||
":@ c #85ABD4",
|
||||
"<@ c #7CA3CD",
|
||||
"[@ c #729AC8",
|
||||
"}@ c #6791C1",
|
||||
"|@ c #5A87BA",
|
||||
"1@ c #5280B4",
|
||||
"2@ c #7A97BB",
|
||||
"3@ c #416290",
|
||||
"4@ c #2F5080",
|
||||
"5@ c #4F6B91",
|
||||
"6@ c #687F9F",
|
||||
"7@ c #7B8FAB",
|
||||
"8@ c #8396B0",
|
||||
"9@ c #8AA1BF",
|
||||
"0@ c #8CACCE",
|
||||
"a@ c #8FB2D8",
|
||||
"b@ c #86AAD2",
|
||||
"c@ c #7DA3CC",
|
||||
"d@ c #749BC7",
|
||||
"e@ c #6993C1",
|
||||
"f@ c #5B88B9",
|
||||
"g@ c #7999C0",
|
||||
"h@ c #587AA5",
|
||||
"i@ c #21416E",
|
||||
"j@ c #516D96",
|
||||
"k@ c #415F8A",
|
||||
"l@ c #567196",
|
||||
"m@ c #637B9E",
|
||||
"n@ c #6F84A3",
|
||||
"o@ c #778BA7",
|
||||
"p@ c #758BAA",
|
||||
"q@ c #7490B3",
|
||||
"r@ c #749BC5",
|
||||
"s@ c #6992C0",
|
||||
"t@ c #799DC4",
|
||||
"u@ c #7291B6",
|
||||
"v@ c #46658C",
|
||||
"w@ c #264878",
|
||||
"x@ c #4F6C94",
|
||||
"y@ c #42608C",
|
||||
"z@ c #294B7D",
|
||||
"A@ c #4A6790",
|
||||
"B@ c #567095",
|
||||
"C@ c #597599",
|
||||
"D@ c #587398",
|
||||
"E@ c #536F96",
|
||||
"F@ c #4F6D95",
|
||||
"G@ c #7690B4",
|
||||
"H@ c #7090B7",
|
||||
"I@ c #4A6991",
|
||||
"J@ c #2B4871",
|
||||
"K@ c #41608C",
|
||||
"L@ c #59749A",
|
||||
"M@ c #234679",
|
||||
"N@ c #214578",
|
||||
"O@ c #3A5A87",
|
||||
"P@ c #47648F",
|
||||
"Q@ c #667EA2",
|
||||
"R@ c #7188A9",
|
||||
"S@ c #4B6892",
|
||||
"T@ c #395985",
|
||||
"U@ c #1C314F",
|
||||
"V@ c #2E4F7D",
|
||||
"W@ c #395986",
|
||||
"X@ c #526E96",
|
||||
"Y@ c #58739A",
|
||||
"Z@ c #5B759B",
|
||||
"`@ c #6A82A5",
|
||||
" # c #627CA0",
|
||||
".# c #365887",
|
||||
"+# c #324B69",
|
||||
"@# c #344B69",
|
||||
"## c #34537D",
|
||||
"$# c #294C7C",
|
||||
"%# c #315383",
|
||||
"&# c #40618D",
|
||||
"*# c #40638F",
|
||||
"=# c #3B5C87",
|
||||
"-# c #36537A",
|
||||
";# c #2E4156",
|
||||
" ",
|
||||
" . ",
|
||||
" + @ # ",
|
||||
" $ % & * = ",
|
||||
" - ; > , ' ) ! ",
|
||||
" ~ { ] ^ / ( _ ",
|
||||
" : < [ } | 1 2 3 4 ",
|
||||
" 5 6 7 8 9 0 a b c d e ",
|
||||
" 7 f g h i j k l m n o p ",
|
||||
" q r s s s t u v w x y z A B ",
|
||||
" C D E s F G H I J K L M N O P ",
|
||||
" Q R S s T U V W X Y Z ` ...+.@.#. ",
|
||||
" $.%.t &.*.=.r -.;.>.,.0 '.).!.~.{.]. ",
|
||||
" ^./.F (._.:.<.[.}.|.}.1.2.3.4.5.6.7.8. ",
|
||||
" 9.v 0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q. ",
|
||||
" r.v s.t.u.v.w.x.y.z.z.A.B.C.D.E.F.G.H.I.J.K. ",
|
||||
" L.M.s N.b.O.P.Q.R.S.T.U.V.W.X.|.Y.Z.`. +.+++ ",
|
||||
" @+#+s $+%+&+*+=+-+;+>+,+'+z.)+!+~+{+]+ +^+/+ ",
|
||||
" (+S s _+:+<+[+}+|+1+2+3+4+5+B.6+7+8+9+0+a+b+ ",
|
||||
" c+T s d+e+f+g+h+i+j+k+l+m+n+W.6+~+o+p+q+r+s+ ",
|
||||
" t+u+s v+w+x+y+z+A+B+C+2+D+n+B.D.Y.E+F+G+H+I+J+ ",
|
||||
" K+L+s M+N.N+O+P+Q+R+S+2+m+5+)+T+U+V+W+X+Y+Z+ ",
|
||||
" `+ @s s .@+@@@#@$@R+%@&@4+z.e.*@=@-@;@>@,@'@ ",
|
||||
" )@!@t s s ~@{@]@^@/@(@=+'+_@:@<@[@}@|@1@2@3@ ",
|
||||
" S #+s s s 4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@ ",
|
||||
" i@j@u s s s G k@l@m@n@o@p@q@a r@s@t@u@v@ ",
|
||||
" w@x@y@s s s s z@_+A@B@C@D@E@F@G@H@I@ ",
|
||||
" J@K@L@y@M@s s N@z@S O@P@Q@R@S@T@ ",
|
||||
" U@V@W@X@L@Y@Z@L@c.`@ #v .#+# ",
|
||||
" @###$#%#&#*#=#-#;# ",
|
||||
" ",
|
||||
" "};
|
0
deluge/src/__init__.py
Normal file
43
deluge/src/core.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# core.py
|
||||
#
|
||||
# Copyright (C) Andrew Resch 2007 <andrewresch@gmail.com>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
# You may 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.
|
||||
#
|
||||
# deluge 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 deluge. If not, write to:
|
||||
# The Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the OpenSSL
|
||||
# library.
|
||||
# You must obey the GNU General Public License in all respects for all of
|
||||
# the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the file(s),
|
||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
# Instantiate the logger
|
||||
import logging
|
||||
log = logging.getLogger("deluge")
|
||||
|
||||
class Core:
|
||||
def __init__(self):
|
||||
log.debug("Core init..")
|
||||
|
||||
def test(self):
|
||||
print "test"
|
61
deluge/src/daemon.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
#
|
||||
# daemon.py
|
||||
#
|
||||
# Copyright (C) Andrew Resch 2007 <andrewresch@gmail.com>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
# You may 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.
|
||||
#
|
||||
# deluge 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 deluge. If not, write to:
|
||||
# The Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the OpenSSL
|
||||
# library.
|
||||
# You must obey the GNU General Public License in all respects for all of
|
||||
# the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the file(s),
|
||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
# Instantiate the logger
|
||||
import logging
|
||||
log = logging.getLogger("deluge")
|
||||
|
||||
import Pyro.core
|
||||
from deluge.core import Core
|
||||
|
||||
class Daemon:
|
||||
def __init__(self):
|
||||
# Instantiate the Manager class
|
||||
self.core = Core()
|
||||
# Initialize the Pyro core and daemon
|
||||
Pyro.core.initServer(banner=0)
|
||||
log.info("Pyro server initiliazed..")
|
||||
self.daemon = Pyro.core.Daemon()
|
||||
# Connect the Manager to the Pyro server
|
||||
obj = Pyro.core.ObjBase()
|
||||
obj.delegateTo(self.core)
|
||||
self.uri = self.daemon.connect(obj, "core")
|
||||
log.debug("uri: %s", self.uri)
|
||||
|
||||
def start(self):
|
||||
# Start the main loop for the pyro daemon
|
||||
self.daemon.requestLoop()
|
||||
|
||||
def getURI(self):
|
||||
# Return the URI for the Pyro server
|
||||
return self.uri
|
99
deluge/src/main.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# main.py
|
||||
#
|
||||
# Copyright (C) Zach Tibbitts 2006 <zach@collegegeek.org>
|
||||
# Copyright (C) Alon Zakai 2006 <kripkensteiner@gmail.com>
|
||||
# Copyright (C) Andrew Resch 2007 <andrewresch@gmail.com>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
# You may 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.
|
||||
#
|
||||
# deluge 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 deluge. If not, write to:
|
||||
# The Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the OpenSSL
|
||||
# library.
|
||||
# You must obey the GNU General Public License in all respects for all of
|
||||
# the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the file(s),
|
||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
# The main starting point for the program. This function is called when the
|
||||
# user runs the command 'deluge'.
|
||||
|
||||
import os
|
||||
import signal
|
||||
|
||||
from optparse import OptionParser
|
||||
import deluge.common
|
||||
from deluge.daemon import Daemon
|
||||
from deluge.ui import Ui
|
||||
|
||||
# Setup the logger
|
||||
import logging
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="[%(levelname)-8s] %(name)s:%(module)s:%(lineno)d %(message)s"
|
||||
)
|
||||
# Get the logger for deluge
|
||||
log = logging.getLogger("deluge")
|
||||
|
||||
def main():
|
||||
log.info("Starting Deluge..")
|
||||
|
||||
# Setup the argument parser
|
||||
parser = OptionParser(usage="%prog [options] [actions]", version=deluge.common.PROGRAM_VERSION)
|
||||
parser.add_option("--daemon", dest="daemon", help="Start Deluge daemon",
|
||||
metavar="DAEMON", action="store_true", default=False)
|
||||
parser.add_option("--ui", dest="ui", help="Start Deluge UI",
|
||||
metavar="UI", action="store_true", default=False)
|
||||
|
||||
# Get the options and args from the OptionParser
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
log.debug("options: %s", options)
|
||||
log.debug("args: %s", args)
|
||||
|
||||
daemon = None
|
||||
pid = None
|
||||
uri = None
|
||||
|
||||
# Start the daemon
|
||||
if options.daemon:
|
||||
log.info("Starting daemon..")
|
||||
daemon = Daemon()
|
||||
uri = daemon.getURI()
|
||||
# We need to fork() the process to run it in the background...
|
||||
pid = os.fork()
|
||||
if not pid:
|
||||
daemon.start()
|
||||
|
||||
# Start the UI
|
||||
if options.ui:
|
||||
log.info("Starting ui..")
|
||||
ui = Ui(uri)
|
||||
|
||||
# Stop Deluge
|
||||
log.info ("Stopping Deluge..")
|
||||
|
||||
# Kill the daemon
|
||||
if pid:
|
||||
log.info("Killing daemon..")
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
|
48
deluge/src/ui.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# ui.py
|
||||
#
|
||||
# Copyright (C) Andrew Resch 2007 <andrewresch@gmail.com>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
# You may 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.
|
||||
#
|
||||
# deluge 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 deluge. If not, write to:
|
||||
# The Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the OpenSSL
|
||||
# library.
|
||||
# You must obey the GNU General Public License in all respects for all of
|
||||
# the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the file(s),
|
||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
# Instantiate the logger
|
||||
import logging
|
||||
log = logging.getLogger("deluge")
|
||||
|
||||
import Pyro.core
|
||||
|
||||
class Ui:
|
||||
def __init__(self, core_uri):
|
||||
log.debug("Ui init..")
|
||||
log.debug("core_uri: %s", core_uri)
|
||||
# Get the core manager from the Pyro server
|
||||
self.core = Pyro.core.getProxyForURI(core_uri)
|
||||
# Test
|
||||
self.core.test()
|
||||
|
231
ez_setup.py
Normal file
|
@ -0,0 +1,231 @@
|
|||
#!python
|
||||
"""Bootstrap setuptools installation
|
||||
|
||||
If you want to use setuptools in your package's setup.py, just include this
|
||||
file in the same directory with it, and add this to the top of your setup.py::
|
||||
|
||||
from ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
|
||||
If you want to require a specific version of setuptools, set a download
|
||||
mirror, or use an alternate download directory, you can do so by supplying
|
||||
the appropriate options to ``use_setuptools()``.
|
||||
|
||||
This file can also be run as a script to install or upgrade setuptools.
|
||||
"""
|
||||
import sys
|
||||
DEFAULT_VERSION = "0.6c6"
|
||||
DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
|
||||
|
||||
md5_data = {
|
||||
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
|
||||
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
|
||||
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
|
||||
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
|
||||
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
|
||||
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
|
||||
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
|
||||
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
|
||||
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
|
||||
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
|
||||
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
|
||||
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
|
||||
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
|
||||
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
|
||||
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
|
||||
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
|
||||
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
|
||||
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
|
||||
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
|
||||
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
|
||||
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
|
||||
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
|
||||
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
|
||||
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
|
||||
}
|
||||
|
||||
import sys, os
|
||||
|
||||
def _validate_md5(egg_name, data):
|
||||
if egg_name in md5_data:
|
||||
from md5 import md5
|
||||
digest = md5(data).hexdigest()
|
||||
if digest != md5_data[egg_name]:
|
||||
print >>sys.stderr, (
|
||||
"md5 validation of %s failed! (Possible download problem?)"
|
||||
% egg_name
|
||||
)
|
||||
sys.exit(2)
|
||||
return data
|
||||
|
||||
|
||||
def use_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||
download_delay=15
|
||||
):
|
||||
"""Automatically find/download setuptools and make it available on sys.path
|
||||
|
||||
`version` should be a valid setuptools version number that is available
|
||||
as an egg for download under the `download_base` URL (which should end with
|
||||
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
|
||||
it is not already available. If `download_delay` is specified, it should
|
||||
be the number of seconds that will be paused before initiating a download,
|
||||
should one be required. If an older version of setuptools is installed,
|
||||
this routine will print a message to ``sys.stderr`` and raise SystemExit in
|
||||
an attempt to abort the calling script.
|
||||
"""
|
||||
try:
|
||||
import setuptools
|
||||
if setuptools.__version__ == '0.0.1':
|
||||
print >>sys.stderr, (
|
||||
"You have an obsolete version of setuptools installed. Please\n"
|
||||
"remove it from your system entirely before rerunning this script."
|
||||
)
|
||||
sys.exit(2)
|
||||
except ImportError:
|
||||
egg = download_setuptools(version, download_base, to_dir, download_delay)
|
||||
sys.path.insert(0, egg)
|
||||
import setuptools; setuptools.bootstrap_install_from = egg
|
||||
|
||||
import pkg_resources
|
||||
try:
|
||||
pkg_resources.require("setuptools>="+version)
|
||||
|
||||
except pkg_resources.VersionConflict, e:
|
||||
# XXX could we install in a subprocess here?
|
||||
print >>sys.stderr, (
|
||||
"The required version of setuptools (>=%s) is not available, and\n"
|
||||
"can't be installed while this script is running. Please install\n"
|
||||
" a more recent version first.\n\n(Currently using %r)"
|
||||
) % (version, e.args[0])
|
||||
sys.exit(2)
|
||||
|
||||
def download_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||
delay = 15
|
||||
):
|
||||
"""Download setuptools from a specified location and return its filename
|
||||
|
||||
`version` should be a valid setuptools version number that is available
|
||||
as an egg for download under the `download_base` URL (which should end
|
||||
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||
`delay` is the number of seconds to pause before an actual download attempt.
|
||||
"""
|
||||
import urllib2, shutil
|
||||
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
||||
url = download_base + egg_name
|
||||
saveto = os.path.join(to_dir, egg_name)
|
||||
src = dst = None
|
||||
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||
try:
|
||||
from distutils import log
|
||||
if delay:
|
||||
log.warn("""
|
||||
---------------------------------------------------------------------------
|
||||
This script requires setuptools version %s to run (even to display
|
||||
help). I will attempt to download it for you (from
|
||||
%s), but
|
||||
you may need to enable firewall access for this script first.
|
||||
I will start the download in %d seconds.
|
||||
|
||||
(Note: if this machine does not have network access, please obtain the file
|
||||
|
||||
%s
|
||||
|
||||
and place it in this directory before rerunning this script.)
|
||||
---------------------------------------------------------------------------""",
|
||||
version, download_base, delay, url
|
||||
); from time import sleep; sleep(delay)
|
||||
log.warn("Downloading %s", url)
|
||||
src = urllib2.urlopen(url)
|
||||
# Read/write all in one block, so we don't create a corrupt file
|
||||
# if the download is interrupted.
|
||||
data = _validate_md5(egg_name, src.read())
|
||||
dst = open(saveto,"wb"); dst.write(data)
|
||||
finally:
|
||||
if src: src.close()
|
||||
if dst: dst.close()
|
||||
return os.path.realpath(saveto)
|
||||
|
||||
def main(argv, version=DEFAULT_VERSION):
|
||||
"""Install or upgrade setuptools and EasyInstall"""
|
||||
|
||||
try:
|
||||
import setuptools
|
||||
except ImportError:
|
||||
egg = None
|
||||
try:
|
||||
egg = download_setuptools(version, delay=0)
|
||||
sys.path.insert(0,egg)
|
||||
from setuptools.command.easy_install import main
|
||||
return main(list(argv)+[egg]) # we're done here
|
||||
finally:
|
||||
if egg and os.path.exists(egg):
|
||||
os.unlink(egg)
|
||||
else:
|
||||
if setuptools.__version__ == '0.0.1':
|
||||
# tell the user to uninstall obsolete version
|
||||
use_setuptools(version)
|
||||
|
||||
req = "setuptools>="+version
|
||||
import pkg_resources
|
||||
try:
|
||||
pkg_resources.require(req)
|
||||
except pkg_resources.VersionConflict:
|
||||
try:
|
||||
from setuptools.command.easy_install import main
|
||||
except ImportError:
|
||||
from easy_install import main
|
||||
main(list(argv)+[download_setuptools(delay=0)])
|
||||
sys.exit(0) # try to force an exit
|
||||
else:
|
||||
if argv:
|
||||
from setuptools.command.easy_install import main
|
||||
main(argv)
|
||||
else:
|
||||
print "Setuptools version",version,"or greater has been installed."
|
||||
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
|
||||
|
||||
|
||||
|
||||
def update_md5(filenames):
|
||||
"""Update our built-in md5 registry"""
|
||||
|
||||
import re
|
||||
from md5 import md5
|
||||
|
||||
for name in filenames:
|
||||
base = os.path.basename(name)
|
||||
f = open(name,'rb')
|
||||
md5_data[base] = md5(f.read()).hexdigest()
|
||||
f.close()
|
||||
|
||||
data = [" %r: %r,\n" % it for it in md5_data.items()]
|
||||
data.sort()
|
||||
repl = "".join(data)
|
||||
|
||||
import inspect
|
||||
srcfile = inspect.getsourcefile(sys.modules[__name__])
|
||||
f = open(srcfile, 'rb'); src = f.read(); f.close()
|
||||
|
||||
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
||||
if not match:
|
||||
print >>sys.stderr, "Internal error!"
|
||||
sys.exit(2)
|
||||
|
||||
src = src[:match.start(1)] + repl + src[match.end(1):]
|
||||
f = open(srcfile,'w')
|
||||
f.write(src)
|
||||
f.close()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
|
||||
update_md5(sys.argv[2:])
|
||||
else:
|
||||
main(sys.argv[1:])
|
||||
|
||||
|
||||
|
||||
|
||||
|
25
libtorrent/AUTHORS
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Written by Arvid Norberg. Copyright (c) 2003-2007
|
||||
|
||||
Lots of testing, suggestions and contributions by:
|
||||
Massaroddel
|
||||
Tianhao Qiu.
|
||||
|
||||
Contributions by:
|
||||
Shyam
|
||||
Magnus Jonsson
|
||||
Daniel Wallin
|
||||
Cory Nelson
|
||||
Stas Khirman
|
||||
Ryan Norton
|
||||
|
||||
Building and maintainance of the autotools scripts:
|
||||
Michael Wojciechowski
|
||||
Peter Koeleman
|
||||
|
||||
Thanks to Reimond Retz for bugfixes, suggestions and testing
|
||||
|
||||
Thanks to University of UmeŒ for providing development and test hardware.
|
||||
|
||||
Project is hosted by sourceforge.
|
||||
|
28
libtorrent/COPYING
Normal file
|
@ -0,0 +1,28 @@
|
|||
Copyright (c) 2003 - 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Rasterbar Software nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
216
libtorrent/ChangeLog
Normal file
|
@ -0,0 +1,216 @@
|
|||
* Fixed bug in URL parser that failed to parse IPv6 addresses
|
||||
* added peer download rate approximation
|
||||
* added port filter for outgoing connection (to prevent
|
||||
triggering firewalls)
|
||||
* made most parameters configurable via session_settings
|
||||
* added encryption support
|
||||
* added parole mode for peers whose data fails the hash check.
|
||||
* optimized heap usage in piece-picker and web seed downloader.
|
||||
* fixed bug in DHT where older write tokens weren't accepted.
|
||||
* added support for sparse files.
|
||||
* introduced speed categories for peers and pieces, to separate
|
||||
slow and fast peers.
|
||||
* added a half-open tcp connection limit that takes all connections
|
||||
in to account, not just peer connections.
|
||||
* added alerts for filtered IPs.
|
||||
* added support for SOCKS4 and 5 proxies and HTTP CONNECT proxies.
|
||||
* fixed proper distributed copies calculation.
|
||||
* added option to use openssl for sha-1 calculations.
|
||||
* optimized the piece picker in the case where a peer is a seed.
|
||||
* added support for local peer discovery
|
||||
* removed the dependency on the compiled boost.date_time library
|
||||
* deprecated torrent_info::print()
|
||||
* added UPnP support
|
||||
* fixed problem where peer interested flags were not updated correctly
|
||||
when pieces were filtered
|
||||
* improvements to ut_pex messages, including support for seed flag
|
||||
* prioritizes upload bandwidth to peers that might send back data
|
||||
* the following functions have been deprecated:
|
||||
void torrent_handle::filter_piece(int index, bool filter) const;
|
||||
void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const;
|
||||
bool torrent_handle::is_piece_filtered(int index) const;
|
||||
std::vector<bool> torrent_handle::filtered_pieces() const;
|
||||
void torrent_handle::filter_files(std::vector<bool> const& files) const;
|
||||
|
||||
instead, use the piece_priority functions.
|
||||
|
||||
* added support for NAT-PMP
|
||||
* added support for piece priorities. Piece filtering is now set as
|
||||
a priority
|
||||
|
||||
release 0.12
|
||||
|
||||
* fixes to make the DHT more compatible
|
||||
* http seed improvements including error reporting and url encoding issues.
|
||||
* fixed bug where directories would be left behind when moving storage
|
||||
in some cases.
|
||||
* fixed crashing bug when restarting or stopping the DHT.
|
||||
* added python binding, using boost.python
|
||||
* improved character conversion on windows when strings are not utf-8.
|
||||
* metadata extension now respects the private flag in the torrent.
|
||||
* made the DHT to only be used as a fallback to trackers by default.
|
||||
* added support for HTTP redirection support for web seeds.
|
||||
* fixed race condition when accessing a torrent that was checking its
|
||||
fast resume data.
|
||||
* fixed a bug in the DHT which could be triggered if the network was
|
||||
dropped or extremely rare cases.
|
||||
* if the download rate is limited, web seeds will now only use left-over
|
||||
bandwidth after all bt peers have used up as much bandwidth as they can.
|
||||
* added the possibility to have libtorrent resolve the countries of
|
||||
the peers in torrents.
|
||||
* improved the bandwidth limiter (it now implements a leaky bucket/node bucket).
|
||||
* improved the HTTP seed downloader to report accurate progress.
|
||||
* added more client peer-id signatures to be recognized.
|
||||
* added support for HTTP servers that skip the CR before the NL at line breaks.
|
||||
* fixed bug in the HTTP code that only accepted headers case sensitive.
|
||||
* fixed bug where one of the session constructors didn't initialize boost.filesystem.
|
||||
* fixed bug when the initial checking of a torrent fails with an exception.
|
||||
* fixed bug in DHT code which would send incorrect announce messages.
|
||||
* fixed bug where the http header parser was case sensitive to the header
|
||||
names.
|
||||
* Implemented an optmization which frees the piece_picker once a torrent
|
||||
turns into a seed.
|
||||
* Added support for uT peer exchange extension, implemented by Massaroddel.
|
||||
* Modified the quota management to offer better bandwidth balancing
|
||||
between peers.
|
||||
* logging now supports multiple sessions (different sessions now log
|
||||
to different directories).
|
||||
* fixed random number generator seed problem, generating the same
|
||||
peer-id for sessions constructed the same second.
|
||||
* added an option to accept multiple connections from the same IP.
|
||||
* improved tracker logging.
|
||||
* moved the file_pool into session. The number of open files is now
|
||||
limited per session.
|
||||
* fixed uninitialized private flag in torrent_info
|
||||
* fixed long standing issue with file.cpp on windows. Replaced the low level
|
||||
io functions used on windows.
|
||||
* made it possible to associate a name with torrents without metadata.
|
||||
* improved http-downloading performance by requesting entire pieces via
|
||||
http.
|
||||
* added plugin interface for extensions. And changed the interface for
|
||||
enabling extensions.
|
||||
|
||||
release 0.11
|
||||
|
||||
* added support for incorrectly encoded paths in torrent files
|
||||
(assumes Latin-1 encoding and converts to UTF-8).
|
||||
* added support for destructing session objects asynchronously.
|
||||
* fixed bug with file_progress() with files = 0 bytes
|
||||
* fixed a race condition bug in udp_tracker_connection that could
|
||||
cause a crash.
|
||||
* fixed bug occuring when increasing the sequenced download threshold
|
||||
with max availability lower than previous threshold.
|
||||
* fixed an integer overflow bug occuring when built with gcc 4.1.x
|
||||
* fixed crasing bug when closing while checking a torrent
|
||||
* fixed bug causing a crash with a torrent with piece length 0
|
||||
* added an extension to the DHT network protocol to support the
|
||||
exchange of nodes with IPv6 addresses.
|
||||
* modified the ip_filter api slightly to support IPv6
|
||||
* modified the api slightly to make sequenced download threshold
|
||||
a per torrent-setting.
|
||||
* changed the address type to support IPv6
|
||||
* fixed bug in piece picker which would not behave as
|
||||
expected with regard to sequenced download threshold.
|
||||
* fixed bug with file_progress() with files > 2 GB.
|
||||
* added --enable-examples option to configure script.
|
||||
* fixed problem with the resource distribution algorithm
|
||||
(controlling e.g upload/download rates).
|
||||
* fixed incorrect asserts in storage related to torrents with
|
||||
zero-sized files.
|
||||
* added support for trackerless torrents (with kademlia DHT).
|
||||
* support for torrents with the private flag set.
|
||||
* support for torrents containing bootstrap nodes for the
|
||||
DHT network.
|
||||
* fixed problem with the configure script on FreeBSD.
|
||||
* limits the pipelining used on url-seeds.
|
||||
* fixed problem where the shutdown always would delay for
|
||||
session_settings::stop_tracker_timeout seconds.
|
||||
* session::listen_on() won't reopen the socket in case the port and
|
||||
interface is the same as the one currently in use.
|
||||
* added http proxy support for web seeds.
|
||||
* fixed problem where upload and download stats could become incorrect
|
||||
in case of high cpu load.
|
||||
* added more clients to the identifiable list.
|
||||
* fixed fingerprint parser to cope with latest Mainline versions.
|
||||
|
||||
release 0.10
|
||||
|
||||
* fixed a bug where the requested number of peers in a tracker request could
|
||||
be too big.
|
||||
* fixed a bug where empty files were not created in full allocation mode.
|
||||
* fixed a bug in storage that would, in rare cases, fail to do a
|
||||
complete check.
|
||||
* exposed more settings for tweaking parameters in the piece-picker,
|
||||
downloader and uploader (http_settings replaced by session_settings).
|
||||
* tweaked default settings to improve high bandwidth transfers.
|
||||
* improved the piece picker performance and made it possible to download
|
||||
popular pieces in sequence to improve disk performance.
|
||||
* added the possibility to control upload and download limits per peer.
|
||||
* fixed problem with re-requesting skipped pieces when peer was sending pieces
|
||||
out of fifo-order.
|
||||
* added support for http seeding (the GetRight protocol)
|
||||
* renamed identifiers called 'id' in the public interface to support linking
|
||||
with Objective.C++
|
||||
* changed the extensions protocol to use the new one, which is also
|
||||
implemented by uTorrent.
|
||||
* factorized the peer_connection and added web_peer_connection which is
|
||||
able to download from http-sources.
|
||||
* converted the network code to use asio (resulted in slight api changes
|
||||
dealing with network addresses).
|
||||
* made libtorrent build in vc7 (patches from Allen Zhao)
|
||||
* fixed bug caused when binding outgoing connections to a non-local interface.
|
||||
* add_torrent() will now throw if called while the session object is
|
||||
being closed.
|
||||
* added the ability to limit the number of simultaneous half-open
|
||||
TCP connections. Flags in peer_info has been added.
|
||||
|
||||
release 0.9.1
|
||||
|
||||
* made the session disable file name checks within the boost.filsystem library
|
||||
* fixed race condition in the sockets
|
||||
* strings that are invalid utf-8 strings are now decoded with the
|
||||
local codepage on windows
|
||||
* added the ability to build libtorrent both as a shared library
|
||||
* client_test can now monitor a directory for torrent files and automatically
|
||||
start and stop downloads while running
|
||||
* fixed problem with file_size() when building on windows with unicode support
|
||||
* added a new torrent state, allocating
|
||||
* added a new alert, metadata_failed_alert
|
||||
* changed the interface to session::add_torrent for some speed optimizations.
|
||||
* greatly improved the command line control of the example client_test.
|
||||
* fixed bug where upload rate limit was not being applied.
|
||||
* files that are being checked will no longer stall files that don't need
|
||||
checking.
|
||||
* changed the way libtorrent identifies support for its excentions
|
||||
to look for 'ext' at the end of the peer-id.
|
||||
* improved performance by adding a circle buffer for the send buffer.
|
||||
* fixed bugs in the http tracker connection when using an http proxy.
|
||||
* fixed problem with storage's file pool when creating torrents and then
|
||||
starting to seed them.
|
||||
* hard limit on remote request queue and timeout on requests (a timeout
|
||||
triggers rerequests). This makes libtorrent work much better with
|
||||
"broken" clients like BitComet which may ignore requests.
|
||||
|
||||
Initial release 0.9
|
||||
|
||||
* multitracker support
|
||||
* serves multiple torrents on a single port and a single thread
|
||||
* supports http proxies and proxy authentication
|
||||
* gzipped tracker-responses
|
||||
* block level piece picker
|
||||
* queues torrents for file check, instead of checking all of them in parallel
|
||||
* uses separate threads for checking files and for main downloader
|
||||
* upload and download rate limits
|
||||
* piece-wise, unordered, incremental file allocation
|
||||
* fast resume support
|
||||
* supports files > 2 gigabytes
|
||||
* supports the no_peer_id=1 extension
|
||||
* support for udp-tracker protocol
|
||||
* number of connections limit
|
||||
* delays sending have messages
|
||||
* can resume pieces downloaded in any order
|
||||
* adjusts the length of the request queue depending on download rate
|
||||
* supports compact=1
|
||||
* selective downloading
|
||||
* ip filter
|
||||
|
3
libtorrent/NEWS
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
initial release of libtorrent 0.9
|
||||
|
25
libtorrent/README
Normal file
|
@ -0,0 +1,25 @@
|
|||
libtorrent is a C++ library that aims to be a good alternative to all the
|
||||
other bittorrent implementations around. It is a
|
||||
library and not a full featured client, although it comes with a working
|
||||
example client.
|
||||
|
||||
The main goals of libtorrent are:
|
||||
|
||||
* to be cpu efficient
|
||||
* to be memory efficient
|
||||
* to be very easy to use
|
||||
|
||||
See docs/manual.html for more detailed build and usage instructions.
|
||||
|
||||
To build with autotools, run:
|
||||
|
||||
./configure
|
||||
|
||||
Followed by
|
||||
|
||||
make
|
||||
|
||||
When libtorrent is built, finish off by running the tests:
|
||||
|
||||
make check
|
||||
|
3
libtorrent/bindings/README.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Documentation covering building and using the python binding for libtorrent
|
||||
is located in the main doc directory. See docs/python_binding.html
|
||||
|
29
libtorrent/bindings/python/Jamfile
Executable file
|
@ -0,0 +1,29 @@
|
|||
import python ;
|
||||
|
||||
use-project /torrent : ../.. ;
|
||||
|
||||
python-extension libtorrent
|
||||
: src/module.cpp
|
||||
src/big_number.cpp
|
||||
src/fingerprint.cpp
|
||||
src/utility.cpp
|
||||
src/session.cpp
|
||||
src/entry.cpp
|
||||
src/torrent_info.cpp
|
||||
src/filesystem.cpp
|
||||
src/torrent_handle.cpp
|
||||
src/torrent_status.cpp
|
||||
src/session_settings.cpp
|
||||
src/version.cpp
|
||||
src/alert.cpp
|
||||
src/datetime.cpp
|
||||
src/extensions.cpp
|
||||
src/peer_plugin.cpp
|
||||
src/docstrings.cpp
|
||||
src/torrent.cpp
|
||||
src/peer_info.cpp
|
||||
/torrent//torrent
|
||||
/boost/python//boost_python
|
||||
: <include>src
|
||||
;
|
||||
|
355
libtorrent/bindings/python/client.py
Executable file
|
@ -0,0 +1,355 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import sys
|
||||
import libtorrent as lt
|
||||
import time
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
class WindowsConsole:
|
||||
def __init__(self):
|
||||
self.console = Console.getconsole()
|
||||
|
||||
def clear(self):
|
||||
self.console.page()
|
||||
|
||||
def write(self, str):
|
||||
self.console.write(str)
|
||||
|
||||
def sleep_and_input(self, seconds):
|
||||
time.sleep(seconds)
|
||||
if msvcrt.kbhit():
|
||||
return msvcrt.getch()
|
||||
return None
|
||||
|
||||
class UnixConsole:
|
||||
def __init__(self):
|
||||
self.fd = sys.stdin
|
||||
self.old = termios.tcgetattr(self.fd.fileno())
|
||||
new = termios.tcgetattr(self.fd.fileno())
|
||||
new[3] = new[3] & ~termios.ICANON
|
||||
new[6][termios.VTIME] = 0
|
||||
new[6][termios.VMIN] = 1
|
||||
termios.tcsetattr(self.fd.fileno(), termios.TCSADRAIN, new)
|
||||
|
||||
sys.exitfunc = self._onexit
|
||||
|
||||
def _onexit(self):
|
||||
termios.tcsetattr(self.fd.fileno(), termios.TCSADRAIN, self.old)
|
||||
|
||||
def clear(self):
|
||||
sys.stdout.write('\033[2J\033[0;0H')
|
||||
sys.stdout.flush()
|
||||
|
||||
def write(self, str):
|
||||
sys.stdout.write(str)
|
||||
sys.stdout.flush()
|
||||
|
||||
def sleep_and_input(self, seconds):
|
||||
read,_,_ = select.select([self.fd.fileno()], [], [], seconds)
|
||||
if len(read) > 0:
|
||||
return self.fd.read(1)
|
||||
return None
|
||||
|
||||
if os.name == 'nt':
|
||||
import Console
|
||||
import msvcrt
|
||||
else:
|
||||
import termios
|
||||
import select
|
||||
|
||||
class PythonExtension(lt.torrent_plugin):
|
||||
def __init__(self, alerts):
|
||||
lt.torrent_plugin.__init__(self)
|
||||
self.alerts = alerts
|
||||
self.alerts.append('PythonExtension')
|
||||
self.count = 0
|
||||
|
||||
def on_piece_pass(self, index):
|
||||
self.alerts.append('got piece %d' % index)
|
||||
|
||||
def on_piece_failed(self, index):
|
||||
self.alerts.append('failed piece %d' % index)
|
||||
|
||||
def tick(self):
|
||||
self.count += 1
|
||||
if self.count >= 10:
|
||||
self.count = 0
|
||||
self.alerts.append('PythonExtension tick')
|
||||
|
||||
def write_line(console, line):
|
||||
console.write(line)
|
||||
|
||||
def add_suffix(val):
|
||||
prefix = ['B', 'kB', 'MB', 'GB', 'TB']
|
||||
for i in range(len(prefix)):
|
||||
if abs(val) < 1000:
|
||||
if i == 0:
|
||||
return '%5.3g%s' % (val, prefix[i])
|
||||
else:
|
||||
return '%4.3g%s' % (val, prefix[i])
|
||||
val /= 1000
|
||||
|
||||
return '%6.3gPB' % val
|
||||
|
||||
def progress_bar(progress, width):
|
||||
progress_chars = int(progress * width + 0.5)
|
||||
return progress_chars * '#' + (width - progress_chars) * '-'
|
||||
|
||||
def print_peer_info(console, peers):
|
||||
|
||||
out = ' down (total ) up (total ) q r flags block progress client\n'
|
||||
|
||||
for p in peers:
|
||||
|
||||
out += '%s/s ' % add_suffix(p.down_speed)
|
||||
out += '(%s) ' % add_suffix(p.total_download)
|
||||
out += '%s/s ' % add_suffix(p.up_speed)
|
||||
out += '(%s) ' % add_suffix(p.total_upload)
|
||||
out += '%2d ' % p.download_queue_length
|
||||
out += '%2d ' % p.upload_queue_length
|
||||
|
||||
if p.flags & lt.peer_info.interesting: out += 'I'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.choked: out += 'C'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.remote_interested: out += 'i'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.remote_choked: out += 'c'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.supports_extensions: out += 'e'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.local_connection: out += 'l'
|
||||
else: out += 'r'
|
||||
out += ' '
|
||||
|
||||
if p.downloading_piece_index >= 0:
|
||||
out += progress_bar(float(p.downloading_progress) / p.downloading_total, 15)
|
||||
else:
|
||||
out += progress_bar(0, 15)
|
||||
out += ' '
|
||||
|
||||
if p.flags & lt.peer_info.handshake:
|
||||
id = 'waiting for handshake'
|
||||
elif p.flags & lt.peer_info.connecting:
|
||||
id = 'connecting to peer'
|
||||
elif p.flags & lt.peer_info.queued:
|
||||
id = 'queued'
|
||||
else:
|
||||
id = p.client
|
||||
|
||||
out += '%s\n' % id[:10]
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
|
||||
def print_download_queue(console, download_queue):
|
||||
|
||||
out = ""
|
||||
|
||||
for e in download_queue:
|
||||
out += '%4d: [' % e['piece_index'];
|
||||
for b in e['blocks']:
|
||||
s = b['state']
|
||||
if s == 3:
|
||||
out += '#'
|
||||
elif s == 2:
|
||||
out += '='
|
||||
elif s == 1:
|
||||
out += '-'
|
||||
else:
|
||||
out += ' '
|
||||
out += ']\n'
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
def main():
|
||||
from optparse import OptionParser
|
||||
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option('-p', '--port',
|
||||
type='int', help='set listening port')
|
||||
|
||||
parser.add_option('-r', '--ratio',
|
||||
type='float', help='set the preferred upload/download ratio. 0 means infinite. Values smaller than 1 are clamped to 1')
|
||||
|
||||
parser.add_option('-d', '--max-download-rate',
|
||||
type='float', help='the maximum download rate given in kB/s. 0 means infinite.')
|
||||
|
||||
parser.add_option('-u', '--max-upload-rate',
|
||||
type='float', help='the maximum upload rate given in kB/s. 0 means infinite.')
|
||||
|
||||
parser.add_option('-s', '--save-path',
|
||||
type='string', help='the path where the downloaded file/folder should be placed.')
|
||||
|
||||
parser.add_option('-a', '--allocation-mode',
|
||||
type='string', help='sets mode used for allocating the downloaded files on disk. Possible options are [full | compact]')
|
||||
|
||||
parser.set_defaults(
|
||||
port=6881
|
||||
, ratio=0
|
||||
, max_download_rate=0
|
||||
, max_upload_rate=0
|
||||
, save_path='./'
|
||||
, allocation_mode='compact'
|
||||
)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.port < 0 or options.port > 65525:
|
||||
options.port = 6881
|
||||
|
||||
options.max_upload_rate *= 1000
|
||||
options.max_download_rate *= 1000
|
||||
|
||||
if options.max_upload_rate <= 0:
|
||||
options.max_upload_rate = -1
|
||||
if options.max_download_rate <= 0:
|
||||
options.max_download_rate = -1
|
||||
|
||||
compact_allocation = options.allocation_mode == 'compact'
|
||||
|
||||
settings = lt.session_settings()
|
||||
settings.user_agent = 'python_client/' + lt.version
|
||||
|
||||
ses = lt.session()
|
||||
ses.set_download_rate_limit(int(options.max_download_rate))
|
||||
ses.set_upload_rate_limit(int(options.max_upload_rate))
|
||||
ses.listen_on(options.port, options.port + 10)
|
||||
ses.set_settings(settings)
|
||||
ses.set_severity_level(lt.alert.severity_levels.info)
|
||||
# ses.add_extension(lt.create_ut_pex_plugin);
|
||||
# ses.add_extension(lt.create_metadata_plugin);
|
||||
|
||||
handles = []
|
||||
alerts = []
|
||||
|
||||
# Extensions
|
||||
# ses.add_extension(lambda x: PythonExtension(alerts))
|
||||
|
||||
for f in args:
|
||||
e = lt.bdecode(open(f, 'rb').read())
|
||||
info = lt.torrent_info(e)
|
||||
print 'Adding \'%s\'...' % info.name()
|
||||
|
||||
try:
|
||||
resume_data = lt.bdecode(open(
|
||||
os.path.join(options.save_path, info.name() + '.fastresume'), 'rb').read())
|
||||
except:
|
||||
resume_data = None
|
||||
|
||||
h = ses.add_torrent(info, options.save_path,
|
||||
resume_data=resume_data, compact_mode=compact_allocation)
|
||||
|
||||
handles.append(h)
|
||||
|
||||
h.set_max_connections(60)
|
||||
h.set_max_uploads(-1)
|
||||
h.set_ratio(options.ratio)
|
||||
h.set_sequenced_download_threshold(15)
|
||||
|
||||
if os.name == 'nt':
|
||||
console = WindowsConsole()
|
||||
else:
|
||||
console = UnixConsole()
|
||||
|
||||
alive = True
|
||||
while alive:
|
||||
console.clear()
|
||||
|
||||
out = ''
|
||||
|
||||
for h in handles:
|
||||
if h.has_metadata():
|
||||
name = h.torrent_info().name()[:40]
|
||||
else:
|
||||
name = '-'
|
||||
out += 'name: %-40s\n' % name
|
||||
|
||||
s = h.status()
|
||||
|
||||
if s.state != lt.torrent_status.seeding:
|
||||
state_str = ['queued', 'checking', 'connecting', 'downloading metadata', \
|
||||
'downloading', 'finished', 'seeding', 'allocating']
|
||||
out += state_str[s.state] + ' '
|
||||
|
||||
out += '%5.4f%% ' % (s.progress*100)
|
||||
out += progress_bar(s.progress, 49)
|
||||
out += '\n'
|
||||
|
||||
out += 'total downloaded: %d Bytes\n' % s.total_done
|
||||
out += 'peers: %d seeds: %d distributed copies: %d\n' % \
|
||||
(s.num_peers, s.num_seeds, s.distributed_copies)
|
||||
out += '\n'
|
||||
|
||||
out += 'download: %s/s (%s) ' \
|
||||
% (add_suffix(s.download_rate), add_suffix(s.total_download))
|
||||
out += 'upload: %s/s (%s) ' \
|
||||
% (add_suffix(s.upload_rate), add_suffix(s.total_upload))
|
||||
out += 'ratio: %s\n' % '0'
|
||||
|
||||
if s.state != lt.torrent_status.seeding:
|
||||
out += 'info-hash: %s\n' % h.info_hash()
|
||||
out += 'next announce: %s\n' % s.next_announce
|
||||
out += 'tracker: %s\n' % s.current_tracker
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
print_peer_info(console, h.get_peer_info())
|
||||
print_download_queue(console, h.get_download_queue())
|
||||
|
||||
if True and s.state != lt.torrent_status.seeding:
|
||||
out = '\n'
|
||||
fp = h.file_progress()
|
||||
ti = h.torrent_info()
|
||||
for f,p in zip(ti.files(), fp):
|
||||
out += progress_bar(p, 20)
|
||||
out += ' ' + f.path + '\n'
|
||||
write_line(console, out)
|
||||
|
||||
write_line(console, 76 * '-' + '\n')
|
||||
write_line(console, '(q)uit), (p)ause), (u)npause), (r)eannounce\n')
|
||||
write_line(console, 76 * '-' + '\n')
|
||||
|
||||
while 1:
|
||||
a = ses.pop_alert()
|
||||
if not a: break
|
||||
alerts.append(a)
|
||||
|
||||
if len(alerts) > 8:
|
||||
del alerts[:len(alerts) - 8]
|
||||
|
||||
for a in alerts:
|
||||
if type(a) == str:
|
||||
write_line(console, a + '\n')
|
||||
else:
|
||||
write_line(console, a.msg() + '\n')
|
||||
|
||||
c = console.sleep_and_input(0.5)
|
||||
|
||||
if not c:
|
||||
continue
|
||||
|
||||
if c == 'r':
|
||||
for h in handles: h.force_reannounce()
|
||||
elif c == 'q':
|
||||
alive = False
|
||||
elif c == 'p':
|
||||
for h in handles: h.pause()
|
||||
elif c == 'u':
|
||||
for h in handles: h.resume()
|
||||
|
||||
for h in handles:
|
||||
if not h.is_valid() or not h.has_metadata():
|
||||
continue
|
||||
h.pause()
|
||||
data = lt.bencode(h.write_resume_data())
|
||||
open(os.path.join(options.save_path, h.torrent_info().name() + '.fastresume'), 'wb').write(data)
|
||||
|
||||
main()
|
||||
|
24
libtorrent/bindings/python/simple_client.py
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import libtorrent as lt
|
||||
import time
|
||||
|
||||
ses = lt.session()
|
||||
ses.listen_on(6881, 6891)
|
||||
|
||||
e = lt.bdecode(open("test.torrent", 'rb').read())
|
||||
info = lt.torrent_info(e)
|
||||
|
||||
h = ses.add_torrent(info, "./", compact_mode = True)
|
||||
|
||||
while (not h.is_seed()):
|
||||
s = h.status()
|
||||
|
||||
state_str = ['queued', 'checking', 'connecting', 'downloading metadata', \
|
||||
'downloading', 'finished', 'seeding', 'allocating']
|
||||
print '%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % \
|
||||
(s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
|
||||
s.num_peers, state_str[s.state])
|
||||
|
||||
time.sleep(1)
|
||||
|
162
libtorrent/bindings/python/src/alert.cpp
Executable file
|
@ -0,0 +1,162 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/alert.hpp>
|
||||
#include <libtorrent/alert_types.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
extern char const* alert_doc;
|
||||
extern char const* alert_msg_doc;
|
||||
extern char const* alert_severity_doc;
|
||||
extern char const* listen_failed_alert_doc;
|
||||
extern char const* file_error_alert_doc;
|
||||
extern char const* tracker_announce_alert_doc;
|
||||
extern char const* tracker_alert_doc;
|
||||
extern char const* tracker_reply_alert_doc;
|
||||
extern char const* tracker_warning_alert_doc;
|
||||
extern char const* url_seed_alert_doc;
|
||||
extern char const* hash_failed_alert_doc;
|
||||
extern char const* peer_ban_alert_doc;
|
||||
extern char const* peer_error_alert_doc;
|
||||
extern char const* invalid_request_alert_doc;
|
||||
extern char const* peer_request_doc;
|
||||
extern char const* torrent_finished_alert_doc;
|
||||
extern char const* metadata_failed_alert_doc;
|
||||
extern char const* metadata_received_alert_doc;
|
||||
extern char const* fastresume_rejected_alert_doc;
|
||||
|
||||
void bind_alert()
|
||||
{
|
||||
using boost::noncopyable;
|
||||
|
||||
{
|
||||
scope alert_scope = class_<alert, noncopyable>("alert", alert_doc, no_init)
|
||||
.def(
|
||||
"msg", &alert::msg, return_value_policy<copy_const_reference>()
|
||||
, alert_msg_doc
|
||||
)
|
||||
.def("severity", &alert::severity, alert_severity_doc)
|
||||
.def(
|
||||
"__str__", &alert::msg, return_value_policy<copy_const_reference>()
|
||||
, alert_msg_doc
|
||||
)
|
||||
;
|
||||
|
||||
enum_<alert::severity_t>("severity_levels")
|
||||
.value("debug", alert::debug)
|
||||
.value("info", alert::info)
|
||||
.value("warning", alert::warning)
|
||||
.value("critical", alert::critical)
|
||||
.value("fatal", alert::fatal)
|
||||
.value("none", alert::none)
|
||||
;
|
||||
}
|
||||
|
||||
class_<listen_failed_alert, bases<alert>, noncopyable>(
|
||||
"listen_failed_alert", listen_failed_alert_doc, no_init
|
||||
);
|
||||
|
||||
class_<file_error_alert, bases<alert>, noncopyable>(
|
||||
"file_error_alert", file_error_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &file_error_alert::handle)
|
||||
;
|
||||
|
||||
class_<tracker_announce_alert, bases<alert>, noncopyable>(
|
||||
"tracker_announce_alert", tracker_announce_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &tracker_announce_alert::handle)
|
||||
;
|
||||
|
||||
class_<tracker_alert, bases<alert>, noncopyable>(
|
||||
"tracker_alert", tracker_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &tracker_alert::handle)
|
||||
.def_readonly("times_in_row", &tracker_alert::times_in_row)
|
||||
.def_readonly("status_code", &tracker_alert::status_code)
|
||||
;
|
||||
|
||||
class_<tracker_reply_alert, bases<alert>, noncopyable>(
|
||||
"tracker_reply_alert", tracker_reply_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &tracker_reply_alert::handle)
|
||||
;
|
||||
|
||||
class_<tracker_warning_alert, bases<alert>, noncopyable>(
|
||||
"tracker_warning_alert", tracker_warning_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &tracker_warning_alert::handle)
|
||||
;
|
||||
|
||||
class_<url_seed_alert, bases<alert>, noncopyable>(
|
||||
"url_seed_alert", url_seed_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("url", &url_seed_alert::url)
|
||||
;
|
||||
|
||||
class_<hash_failed_alert, bases<alert>, noncopyable>(
|
||||
"hash_failed_alert", hash_failed_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &hash_failed_alert::handle)
|
||||
.def_readonly("piece_index", &hash_failed_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<peer_ban_alert, bases<alert>, noncopyable>(
|
||||
"peer_ban_alert", peer_ban_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("ip", &peer_ban_alert::ip)
|
||||
.def_readonly("handle", &peer_ban_alert::handle)
|
||||
;
|
||||
|
||||
class_<peer_error_alert, bases<alert>, noncopyable>(
|
||||
"peer_error_alert", peer_error_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("ip", &peer_error_alert::ip)
|
||||
.def_readonly("pid", &peer_error_alert::pid)
|
||||
;
|
||||
|
||||
class_<invalid_request_alert, bases<alert>, noncopyable>(
|
||||
"invalid_request_alert", invalid_request_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &invalid_request_alert::handle)
|
||||
.def_readonly("ip", &invalid_request_alert::ip)
|
||||
.def_readonly("request", &invalid_request_alert::request)
|
||||
.def_readonly("pid", &invalid_request_alert::pid)
|
||||
;
|
||||
|
||||
class_<peer_request>("peer_request", peer_request_doc)
|
||||
.def_readonly("piece", &peer_request::piece)
|
||||
.def_readonly("start", &peer_request::start)
|
||||
.def_readonly("length", &peer_request::length)
|
||||
.def(self == self)
|
||||
;
|
||||
|
||||
class_<torrent_finished_alert, bases<alert>, noncopyable>(
|
||||
"torrent_finished_alert", torrent_finished_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &torrent_finished_alert::handle)
|
||||
;
|
||||
|
||||
class_<metadata_failed_alert, bases<alert>, noncopyable>(
|
||||
"metadata_failed_alert", metadata_failed_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &metadata_failed_alert::handle)
|
||||
;
|
||||
|
||||
class_<metadata_received_alert, bases<alert>, noncopyable>(
|
||||
"metadata_received_alert", metadata_received_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &metadata_received_alert::handle)
|
||||
;
|
||||
|
||||
class_<fastresume_rejected_alert, bases<alert>, noncopyable>(
|
||||
"fastresume_rejected_alert", fastresume_rejected_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &fastresume_rejected_alert::handle)
|
||||
;
|
||||
}
|
||||
|
20
libtorrent/bindings/python/src/big_number.cpp
Executable file
|
@ -0,0 +1,20 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/peer_id.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void bind_big_number()
|
||||
{
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
class_<big_number>("big_number")
|
||||
.def(self == self)
|
||||
.def(self != self)
|
||||
.def(self < self)
|
||||
.def(self_ns::str(self))
|
||||
;
|
||||
}
|
||||
|
5
libtorrent/bindings/python/src/converters.cpp
Executable file
|
@ -0,0 +1,5 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
81
libtorrent/bindings/python/src/datetime.cpp
Executable file
|
@ -0,0 +1,81 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "optional.hpp"
|
||||
#include <boost/version.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
#if BOOST_VERSION < 103400
|
||||
|
||||
// From Boost 1.34
|
||||
object import(str name)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *n = extract<char *>(name);
|
||||
handle<> module(borrowed(PyImport_ImportModule(n)));
|
||||
return object(module);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
object datetime_timedelta;
|
||||
object datetime_datetime;
|
||||
|
||||
struct time_duration_to_python
|
||||
{
|
||||
static PyObject* convert(boost::posix_time::time_duration const& d)
|
||||
{
|
||||
object result = datetime_timedelta(
|
||||
0 // days
|
||||
, 0 // seconds
|
||||
, d.total_microseconds()
|
||||
);
|
||||
|
||||
return incref(result.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
struct ptime_to_python
|
||||
{
|
||||
static PyObject* convert(boost::posix_time::ptime const& pt)
|
||||
{
|
||||
boost::gregorian::date date = pt.date();
|
||||
boost::posix_time::time_duration td = pt.time_of_day();
|
||||
|
||||
object result = datetime_datetime(
|
||||
(int)date.year()
|
||||
, (int)date.month()
|
||||
, (int)date.day()
|
||||
, td.hours()
|
||||
, td.minutes()
|
||||
, td.seconds()
|
||||
);
|
||||
|
||||
return incref(result.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
void bind_datetime()
|
||||
{
|
||||
object datetime = import("datetime").attr("__dict__");
|
||||
|
||||
datetime_timedelta = datetime["timedelta"];
|
||||
datetime_datetime = datetime["datetime"];
|
||||
|
||||
to_python_converter<
|
||||
boost::posix_time::time_duration
|
||||
, time_duration_to_python
|
||||
>();
|
||||
|
||||
to_python_converter<
|
||||
boost::posix_time::ptime
|
||||
, ptime_to_python
|
||||
>();
|
||||
|
||||
optional_to_python<boost::posix_time::ptime>();
|
||||
}
|
||||
|
266
libtorrent/bindings/python/src/docstrings.cpp
Executable file
|
@ -0,0 +1,266 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// -- torrent_status --------------------------------------------------------
|
||||
|
||||
char const* torrent_status_doc =
|
||||
"Represents the current status for a torrent.\n"
|
||||
"Returned by `torrent_handle.status()`.";
|
||||
|
||||
char const* torrent_status_state_doc =
|
||||
"The torrents current task. One of `torrent_status.states`.";
|
||||
|
||||
char const* torrent_status_paused_doc =
|
||||
"Indicates if this torrent is paused or not.";
|
||||
|
||||
char const* torrent_status_progress_doc =
|
||||
"A value in the range [0, 1], that represents the progress of\n"
|
||||
"the torrent's current task.";
|
||||
|
||||
char const* torrent_status_next_announce_doc =
|
||||
"The time until the torrent will announce itself to the\n"
|
||||
"tracker. An instance of `datetime.timedelta`.";
|
||||
|
||||
char const* torrent_status_announce_interval_doc =
|
||||
"The interval at which the torrent will reannounce itself to the\n"
|
||||
"tracker. An instance of `datetime.timedelta`.";
|
||||
|
||||
char const* torrent_status_current_tracker_doc =
|
||||
"The URL of the last working tracker. If no tracker request has\n"
|
||||
"been successful yet, it's set to an empty string.";
|
||||
|
||||
char const* torrent_status_total_download_doc = "";
|
||||
char const* torrent_status_total_upload_doc = "";
|
||||
char const* torrent_status_total_payload_download_doc = "";
|
||||
char const* torrent_status_total_payload_upload_doc = "";
|
||||
char const* torrent_status_total_failed_bytes_doc = "";
|
||||
|
||||
// -- session_status --------------------------------------------------------
|
||||
|
||||
char const* session_status_doc =
|
||||
"";
|
||||
char const* session_status_has_incoming_connections_doc =
|
||||
"";
|
||||
char const* session_status_upload_rate_doc =
|
||||
"";
|
||||
char const* session_status_download_rate_doc =
|
||||
"";
|
||||
char const* session_status_payload_upload_rate_doc =
|
||||
"";
|
||||
char const* session_status_payload_download_rate_doc =
|
||||
"";
|
||||
char const* session_status_total_download_doc =
|
||||
"";
|
||||
char const* session_status_total_upload_doc =
|
||||
"";
|
||||
char const* session_status_total_payload_download_doc =
|
||||
"";
|
||||
char const* session_status_total_payload_upload_doc =
|
||||
"";
|
||||
char const* session_status_num_peers_doc =
|
||||
"";
|
||||
char const* session_status_dht_nodes_doc =
|
||||
"";
|
||||
char const* session_status_cache_nodes_doc =
|
||||
"";
|
||||
char const* session_status_dht_torrents_doc =
|
||||
"";
|
||||
|
||||
// -- session ---------------------------------------------------------------
|
||||
|
||||
char const* session_doc =
|
||||
"";
|
||||
char const* session_init_doc =
|
||||
"The `fingerprint` is a short string that will be used in\n"
|
||||
"the peer-id to identify the client and the client's version.\n"
|
||||
"For more details see the `fingerprint` class.\n"
|
||||
"The constructor that only takes a fingerprint will not open\n"
|
||||
"a listen port for the session, to get it running you'll have\n"
|
||||
"to call `session.listen_on()`.";
|
||||
|
||||
char const* session_listen_on_doc =
|
||||
"";
|
||||
char const* session_is_listening_doc =
|
||||
"";
|
||||
char const* session_listen_port_doc =
|
||||
"";
|
||||
|
||||
char const* session_status_m_doc =
|
||||
"Returns an instance of `session_status` with session wide-statistics\n"
|
||||
"and status";
|
||||
|
||||
char const* session_start_dht_doc =
|
||||
"";
|
||||
char const* session_stop_dht_doc =
|
||||
"";
|
||||
char const* session_dht_state_doc =
|
||||
"";
|
||||
|
||||
char const* session_add_torrent_doc =
|
||||
"Adds a new torrent to the session. Return a `torrent_handle`.\n"
|
||||
"\n"
|
||||
":Parameters:\n"
|
||||
" - `torrent_info`: `torrent_info` instance representing the torrent\n"
|
||||
" you want to add.\n"
|
||||
" - `save_path`: The path to the directory where files will be saved.\n"
|
||||
" - `resume_data (optional)`: The resume data for this torrent, as decoded\n"
|
||||
" with `bdecode()`. This can be acquired from a running torrent with\n"
|
||||
" `torrent_handle.write_resume_data()`.\n"
|
||||
" - `compact_mode (optional)`: If set to true (default), the storage\n"
|
||||
" will grow as more pieces are downloaded, and pieces are rearranged\n"
|
||||
" to finally be in their correct places once the entire torrent has\n"
|
||||
" been downloaded. If it is false, the entire storage is allocated\n"
|
||||
" before download begins. I.e. the files contained in the torrent\n"
|
||||
" are filled with zeros, and each downloaded piece is put in its\n"
|
||||
" final place directly when downloaded.\n"
|
||||
" - `block_size (optional)`: Sets the preferred request size, i.e.\n"
|
||||
" the number of bytes to request from a peer at a time. This block size\n"
|
||||
" must be a divisor of the piece size, and since the piece size is an\n"
|
||||
" even power of 2, so must the block size be. If the block size given\n"
|
||||
" here turns out to be greater than the piece size, it will simply be\n"
|
||||
" clamped to the piece size.\n"
|
||||
"\n"
|
||||
":Exceptions:\n"
|
||||
" - `duplicate_torrent`: If the torrent you are trying to add already\n"
|
||||
" exists in the session (is either queued for checking, being checked\n"
|
||||
" or downloading) `add_torrent()` will throw `duplicate_torrent`.\n";
|
||||
|
||||
char const* session_remove_torrent_doc =
|
||||
"Close all peer connections associated with the torrent and tell the\n"
|
||||
"tracker that we've stopped participating in the swarm.";
|
||||
|
||||
char const* session_set_download_rate_limit_doc =
|
||||
"";
|
||||
char const* session_set_upload_rate_limit_doc =
|
||||
"";
|
||||
char const* session_set_max_uploads_doc =
|
||||
"";
|
||||
char const* session_set_max_connections_doc =
|
||||
"";
|
||||
char const* session_set_max_half_open_connections_doc =
|
||||
"Sets the maximum number of half-open connections libtorrent will\n"
|
||||
"have when connecting to peers. A half-open connection is one where\n"
|
||||
"connect() has been called, but the connection still hasn't been\n"
|
||||
"established (nor failed). Windows XP Service Pack 2 sets a default,\n"
|
||||
"system wide, limit of the number of half-open connections to 10. So, \n"
|
||||
"this limit can be used to work nicer together with other network\n"
|
||||
"applications on that system. The default is to have no limit, and passing\n"
|
||||
"-1 as the limit, means to have no limit. When limiting the number of\n"
|
||||
"simultaneous connection attempts, peers will be put in a queue waiting\n"
|
||||
"for their turn to get connected.";
|
||||
|
||||
char const* session_set_settings_doc =
|
||||
"";
|
||||
char const* session_set_severity_level_doc =
|
||||
"";
|
||||
char const* session_pop_alert_doc =
|
||||
"";
|
||||
|
||||
// -- alert -----------------------------------------------------------------
|
||||
|
||||
char const* alert_doc =
|
||||
"Base class for all concrete alert classes.";
|
||||
|
||||
char const* alert_msg_doc =
|
||||
"Returns a string describing this alert.";
|
||||
|
||||
char const* alert_severity_doc =
|
||||
"Returns the severity level for this alert, one of `alert.severity_levels`.";
|
||||
|
||||
char const* listen_failed_alert_doc =
|
||||
"This alert is generated when none of the ports, given in the\n"
|
||||
"port range, to `session` can be opened for listening. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.fatal`.";
|
||||
|
||||
char const* file_error_alert_doc =
|
||||
"If the storage fails to read or write files that it needs access\n"
|
||||
"to, this alert is generated and the torrent is paused. It is\n"
|
||||
"generated as severity level `alert.severity_levels.fatal`.";
|
||||
|
||||
char const* tracker_announce_alert_doc =
|
||||
"This alert is generated each time a tracker announce is sent\n"
|
||||
"(or attempted to be sent). It is generated at severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* tracker_alert_doc =
|
||||
"This alert is generated on tracker time outs, premature\n"
|
||||
"disconnects, invalid response or a HTTP response other than\n"
|
||||
"\"200 OK\". From the alert you can get the handle to the torrent\n"
|
||||
"the tracker belongs to. This alert is generated as severity level\n"
|
||||
"`alert.severity_levels.warning`.";
|
||||
|
||||
char const* tracker_reply_alert_doc =
|
||||
"This alert is only for informational purpose. It is generated when\n"
|
||||
"a tracker announce succeeds. It is generated with severity level\n"
|
||||
"`alert.severity_levels.info`.";
|
||||
|
||||
char const* tracker_warning_alert_doc =
|
||||
"This alert is triggered if the tracker reply contains a warning\n"
|
||||
"field. Usually this means that the tracker announce was successful\n"
|
||||
", but the tracker has a message to the client. The message string in\n"
|
||||
"the alert will contain the warning message from the tracker. It is\n"
|
||||
"generated with severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* url_seed_alert_doc =
|
||||
"This alert is generated when a HTTP seed name lookup fails. This\n"
|
||||
"alert is generated as severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* hash_failed_alert_doc =
|
||||
"This alert is generated when a finished piece fails its hash check.\n"
|
||||
"You can get the handle to the torrent which got the failed piece\n"
|
||||
"and the index of the piece itself from the alert. This alert is\n"
|
||||
"generated as severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* peer_ban_alert_doc =
|
||||
"This alert is generated when a peer is banned because it has sent\n"
|
||||
"too many corrupt pieces to us. It is generated at severity level\n"
|
||||
"`alert.severity_levels.info`. The handle member is a `torrent_handle` to the torrent that\n"
|
||||
"this peer was a member of.";
|
||||
|
||||
char const* peer_error_alert_doc =
|
||||
"This alert is generated when a peer sends invalid data over the\n"
|
||||
"peer-peer protocol. The peer will be disconnected, but you get its\n"
|
||||
"ip address from the alert, to identify it. This alert is generated\n"
|
||||
"is severity level `alert.severity_levels.debug`.";
|
||||
|
||||
char const* invalid_request_alert_doc =
|
||||
"This is a debug alert that is generated by an incoming invalid\n"
|
||||
"piece request. The handle is a handle to the torrent the peer\n"
|
||||
"is a member of. Ip is the address of the peer and the request is\n"
|
||||
"the actual incoming request from the peer. The alert is generated\n"
|
||||
"as severity level `alert.severity_levels.debug`.";
|
||||
|
||||
char const* peer_request_doc =
|
||||
"The `peer_request` contains the values the client sent in its\n"
|
||||
"request message. ``piece`` is the index of the piece it want data\n"
|
||||
"from, ``start`` is the offset within the piece where the data should be\n"
|
||||
"read, and ``length`` is the amount of data it wants.";
|
||||
|
||||
char const* torrent_finished_alert_doc =
|
||||
"This alert is generated when a torrent switches from being a\n"
|
||||
"downloader to a seed. It will only be generated once per torrent.\n"
|
||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* metadata_failed_alert_doc =
|
||||
"This alert is generated when the metadata has been completely\n"
|
||||
"received and the info-hash failed to match it. i.e. the\n"
|
||||
"metadata that was received was corrupt. libtorrent will\n"
|
||||
"automatically retry to fetch it in this case. This is only\n"
|
||||
"relevant when running a torrent-less download, with the metadata\n"
|
||||
"extension provided by libtorrent. It is generated at severity\n"
|
||||
"level `alert.severity_levels.info`.";
|
||||
|
||||
char const* metadata_received_alert_doc =
|
||||
"This alert is generated when the metadata has been completely\n"
|
||||
"received and the torrent can start downloading. It is not generated\n"
|
||||
"on torrents that are started with metadata, but only those that\n"
|
||||
"needs to download it from peers (when utilizing the libtorrent\n"
|
||||
"extension). It is generated at severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* fastresume_rejected_alert_doc =
|
||||
"This alert is generated when a fastresume file has been passed\n"
|
||||
"to `session.add_torrent` but the files on disk did not match the\n"
|
||||
"fastresume file. The string explains the reason why the resume\n"
|
||||
"file was rejected. It is generated at severity level `alert.severity_levels.warning`.";
|
||||
|
132
libtorrent/bindings/python/src/entry.cpp
Executable file
|
@ -0,0 +1,132 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
struct entry_to_python
|
||||
{
|
||||
static object convert(entry::list_type const& l)
|
||||
{
|
||||
list result;
|
||||
|
||||
for (entry::list_type::const_iterator i(l.begin()), e(l.end()); i != e; ++i)
|
||||
{
|
||||
result.append(*i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static object convert(entry::dictionary_type const& d)
|
||||
{
|
||||
dict result;
|
||||
|
||||
for (entry::dictionary_type::const_iterator i(d.begin()), e(d.end()); i != e; ++i)
|
||||
result[i->first] = i->second;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static object convert0(entry const& e)
|
||||
{
|
||||
switch (e.type())
|
||||
{
|
||||
case entry::int_t:
|
||||
return object(e.integer());
|
||||
case entry::string_t:
|
||||
return object(e.string());
|
||||
case entry::list_t:
|
||||
return convert(e.list());
|
||||
case entry::dictionary_t:
|
||||
return convert(e.dict());
|
||||
default:
|
||||
return object();
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* convert(entry const& e)
|
||||
{
|
||||
return incref(convert0(e).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
struct entry_from_python
|
||||
{
|
||||
entry_from_python()
|
||||
{
|
||||
converter::registry::push_back(
|
||||
&convertible, &construct, type_id<entry>()
|
||||
);
|
||||
}
|
||||
|
||||
static void* convertible(PyObject* e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
static entry construct0(object e)
|
||||
{
|
||||
if (extract<dict>(e).check())
|
||||
{
|
||||
dict d = extract<dict>(e);
|
||||
list items(d.items());
|
||||
std::size_t length = extract<std::size_t>(items.attr("__len__")());
|
||||
entry result(entry::dictionary_t);
|
||||
|
||||
for (std::size_t i = 0; i < length; ++i)
|
||||
{
|
||||
result.dict().insert(
|
||||
std::make_pair(
|
||||
extract<char const*>(items[i][0])()
|
||||
, construct0(items[i][1])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (extract<list>(e).check())
|
||||
{
|
||||
list l = extract<list>(e);
|
||||
|
||||
std::size_t length = extract<std::size_t>(l.attr("__len__")());
|
||||
entry result(entry::list_t);
|
||||
|
||||
for (std::size_t i = 0; i < length; ++i)
|
||||
{
|
||||
result.list().push_back(construct0(l[i]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (extract<str>(e).check())
|
||||
{
|
||||
return entry(extract<std::string>(e)());
|
||||
}
|
||||
else if (extract<entry::integer_type>(e).check())
|
||||
{
|
||||
return entry(extract<entry::integer_type>(e)());
|
||||
}
|
||||
|
||||
return entry();
|
||||
}
|
||||
|
||||
static void construct(PyObject* e, converter::rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* storage = ((converter::rvalue_from_python_storage<entry>*)data)->storage.bytes;
|
||||
new (storage) entry(construct0(object(borrowed(e))));
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
void bind_entry()
|
||||
{
|
||||
to_python_converter<entry, entry_to_python>();
|
||||
entry_from_python();
|
||||
}
|
||||
|
148
libtorrent/bindings/python/src/extensions.cpp
Executable file
|
@ -0,0 +1,148 @@
|
|||
// Copyright Daniel Wallin, Arvid Norberg 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/extensions.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/peer_request.hpp>
|
||||
#include <libtorrent/peer_connection.hpp>
|
||||
#include <libtorrent/extensions/ut_pex.hpp>
|
||||
#include <libtorrent/extensions/metadata_transfer.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct torrent_plugin_wrap : torrent_plugin, wrapper<torrent_plugin>
|
||||
{
|
||||
boost::shared_ptr<peer_plugin> new_connection(peer_connection* p)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("new_connection"))
|
||||
return f(ptr(p));
|
||||
return torrent_plugin::new_connection(p);
|
||||
}
|
||||
|
||||
boost::shared_ptr<peer_plugin> default_new_connection(peer_connection* p)
|
||||
{
|
||||
return this->torrent_plugin::new_connection(p);
|
||||
}
|
||||
|
||||
void on_piece_pass(int index)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_piece_pass"))
|
||||
f(index);
|
||||
else
|
||||
torrent_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void default_on_piece_pass(int index)
|
||||
{
|
||||
this->torrent_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void on_piece_failed(int index)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_piece_failed"))
|
||||
f(index);
|
||||
else
|
||||
torrent_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void default_on_piece_failed(int index)
|
||||
{
|
||||
return this->torrent_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("tick"))
|
||||
f();
|
||||
else
|
||||
torrent_plugin::tick();
|
||||
}
|
||||
|
||||
void default_tick()
|
||||
{
|
||||
return this->torrent_plugin::tick();
|
||||
}
|
||||
|
||||
bool on_pause()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_pause"))
|
||||
return f();
|
||||
return torrent_plugin::on_pause();
|
||||
}
|
||||
|
||||
bool default_on_pause()
|
||||
{
|
||||
return this->torrent_plugin::on_pause();
|
||||
}
|
||||
|
||||
bool on_resume()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_resume"))
|
||||
return f();
|
||||
return torrent_plugin::on_resume();
|
||||
}
|
||||
|
||||
bool default_on_resume()
|
||||
{
|
||||
return this->torrent_plugin::on_resume();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_extensions()
|
||||
{
|
||||
class_<
|
||||
torrent_plugin_wrap, boost::shared_ptr<torrent_plugin_wrap>, boost::noncopyable
|
||||
>("torrent_plugin")
|
||||
.def(
|
||||
"new_connection"
|
||||
, &torrent_plugin::new_connection, &torrent_plugin_wrap::default_new_connection
|
||||
)
|
||||
.def(
|
||||
"on_piece_pass"
|
||||
, &torrent_plugin::on_piece_pass, &torrent_plugin_wrap::default_on_piece_pass
|
||||
)
|
||||
.def(
|
||||
"on_piece_failed"
|
||||
, &torrent_plugin::on_piece_failed, &torrent_plugin_wrap::default_on_piece_failed
|
||||
)
|
||||
.def(
|
||||
"tick"
|
||||
, &torrent_plugin::tick, &torrent_plugin_wrap::default_tick
|
||||
)
|
||||
.def(
|
||||
"on_pause"
|
||||
, &torrent_plugin::on_pause, &torrent_plugin_wrap::default_on_pause
|
||||
)
|
||||
.def(
|
||||
"on_resume"
|
||||
, &torrent_plugin::on_resume, &torrent_plugin_wrap::default_on_resume
|
||||
);
|
||||
|
||||
// TODO move to it's own file
|
||||
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
|
||||
|
||||
def("create_ut_pex_plugin", create_ut_pex_plugin);
|
||||
def("create_metadata_plugin", create_metadata_plugin);
|
||||
}
|
||||
|
51
libtorrent/bindings/python/src/filesystem.cpp
Executable file
|
@ -0,0 +1,51 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct path_to_python
|
||||
{
|
||||
static PyObject* convert(boost::filesystem::path const& p)
|
||||
{
|
||||
return incref(object(p.string()).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
struct path_from_python
|
||||
{
|
||||
path_from_python()
|
||||
{
|
||||
converter::registry::push_back(
|
||||
&convertible, &construct, type_id<boost::filesystem::path>()
|
||||
);
|
||||
}
|
||||
|
||||
static void* convertible(PyObject* x)
|
||||
{
|
||||
return PyString_Check(x) ? x : 0;
|
||||
}
|
||||
|
||||
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* storage = ((converter::rvalue_from_python_storage<
|
||||
boost::filesystem::path
|
||||
>*)data)->storage.bytes;
|
||||
new (storage) boost::filesystem::path(PyString_AsString(x));
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
void bind_filesystem()
|
||||
{
|
||||
to_python_converter<boost::filesystem::path, path_to_python>();
|
||||
path_from_python();
|
||||
|
||||
using namespace boost::filesystem;
|
||||
if (path::default_name_check_writable())
|
||||
path::default_name_check(no_check);
|
||||
}
|
||||
|
27
libtorrent/bindings/python/src/fingerprint.cpp
Executable file
|
@ -0,0 +1,27 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/fingerprint.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void bind_fingerprint()
|
||||
{
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
class_<fingerprint>("fingerprint", no_init)
|
||||
.def(
|
||||
init<char const*,int,int,int,int>(
|
||||
(arg("id"), "major", "minor", "revision", "tag")
|
||||
)
|
||||
)
|
||||
.def("__str__", &fingerprint::to_string)
|
||||
.def_readonly("name", &fingerprint::name)
|
||||
.def_readonly("major_version", &fingerprint::major_version)
|
||||
.def_readonly("minor_version", &fingerprint::minor_version)
|
||||
.def_readonly("revision_version", &fingerprint::revision_version)
|
||||
.def_readonly("tag_version", &fingerprint::tag_version)
|
||||
;
|
||||
}
|
||||
|
144
libtorrent/bindings/python/src/gil.hpp
Executable file
|
@ -0,0 +1,144 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef GIL_070107_HPP
|
||||
# define GIL_070107_HPP
|
||||
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/def_visitor.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/mpl/at.hpp>
|
||||
|
||||
//namespace libtorrent { namespace python {
|
||||
|
||||
// RAII helper to release GIL.
|
||||
struct allow_threading_guard
|
||||
{
|
||||
allow_threading_guard()
|
||||
: save(PyEval_SaveThread())
|
||||
{}
|
||||
|
||||
~allow_threading_guard()
|
||||
{
|
||||
PyEval_RestoreThread(save);
|
||||
}
|
||||
|
||||
PyThreadState* save;
|
||||
};
|
||||
|
||||
struct lock_gil
|
||||
{
|
||||
lock_gil()
|
||||
: state(PyGILState_Ensure())
|
||||
{}
|
||||
|
||||
~lock_gil()
|
||||
{
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
PyGILState_STATE state;
|
||||
};
|
||||
|
||||
template <class F, class R>
|
||||
struct allow_threading
|
||||
{
|
||||
allow_threading(F fn)
|
||||
: fn(fn)
|
||||
{}
|
||||
|
||||
template <class A0>
|
||||
R operator()(A0& a0)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)();
|
||||
}
|
||||
|
||||
template <class A0, class A1>
|
||||
R operator()(A0& a0, A1& a1)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2>
|
||||
R operator()(A0& a0, A1& a1, A2& a2)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3,a4);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3,a4,a5);
|
||||
}
|
||||
|
||||
F fn;
|
||||
};
|
||||
|
||||
template <class F>
|
||||
struct visitor : boost::python::def_visitor<visitor<F> >
|
||||
{
|
||||
visitor(F fn)
|
||||
: fn(fn)
|
||||
{}
|
||||
|
||||
template <class Class, class Options, class Signature>
|
||||
void visit_aux(
|
||||
Class& cl, char const* name
|
||||
, Options const& options, Signature const& signature) const
|
||||
{
|
||||
typedef typename boost::mpl::at_c<Signature,0>::type return_type;
|
||||
|
||||
cl.def(
|
||||
name
|
||||
, boost::python::make_function(
|
||||
allow_threading<F, return_type>(fn)
|
||||
, options.policies()
|
||||
, options.keywords()
|
||||
, signature
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class Class, class Options>
|
||||
void visit(Class& cl, char const* name, Options const& options) const
|
||||
{
|
||||
this->visit_aux(
|
||||
cl, name, options
|
||||
, boost::python::detail::get_signature(fn, (typename Class::wrapped_type*)0)
|
||||
);
|
||||
}
|
||||
|
||||
F fn;
|
||||
};
|
||||
|
||||
// Member function adaptor that releases and aqcuires the GIL
|
||||
// around the function call.
|
||||
template <class F>
|
||||
visitor<F> allow_threads(F fn)
|
||||
{
|
||||
return visitor<F>(fn);
|
||||
}
|
||||
|
||||
//}} // namespace libtorrent::python
|
||||
|
||||
#endif // GIL_070107_HPP
|
||||
|
48
libtorrent/bindings/python/src/module.cpp
Executable file
|
@ -0,0 +1,48 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
void bind_utility();
|
||||
void bind_fingerprint();
|
||||
void bind_big_number();
|
||||
void bind_session();
|
||||
void bind_entry();
|
||||
void bind_torrent_info();
|
||||
void bind_filesystem();
|
||||
void bind_torrent_handle();
|
||||
void bind_torrent_status();
|
||||
void bind_session_settings();
|
||||
void bind_version();
|
||||
void bind_alert();
|
||||
void bind_datetime();
|
||||
void bind_extensions();
|
||||
void bind_peer_plugin();
|
||||
void bind_torrent();
|
||||
void bind_peer_info();
|
||||
|
||||
BOOST_PYTHON_MODULE(libtorrent)
|
||||
{
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
|
||||
bind_utility();
|
||||
bind_fingerprint();
|
||||
bind_big_number();
|
||||
bind_entry();
|
||||
bind_session();
|
||||
bind_torrent_info();
|
||||
bind_filesystem();
|
||||
bind_torrent_handle();
|
||||
bind_torrent_status();
|
||||
bind_session_settings();
|
||||
bind_version();
|
||||
bind_alert();
|
||||
bind_datetime();
|
||||
bind_extensions();
|
||||
bind_peer_plugin();
|
||||
bind_torrent();
|
||||
bind_peer_info();
|
||||
}
|
||||
|
31
libtorrent/bindings/python/src/optional.hpp
Executable file
|
@ -0,0 +1,31 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef OPTIONAL_070108_HPP
|
||||
# define OPTIONAL_070108_HPP
|
||||
|
||||
# include <boost/python.hpp>
|
||||
# include <boost/optional.hpp>
|
||||
|
||||
template <class T>
|
||||
struct optional_to_python
|
||||
{
|
||||
optional_to_python()
|
||||
{
|
||||
boost::python::to_python_converter<
|
||||
boost::optional<T>, optional_to_python<T>
|
||||
>();
|
||||
}
|
||||
|
||||
static PyObject* convert(boost::optional<T> const& x)
|
||||
{
|
||||
if (!x)
|
||||
return boost::python::incref(Py_None);
|
||||
|
||||
return boost::python::incref(boost::python::object(*x).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OPTIONAL_070108_HPP
|
||||
|
63
libtorrent/bindings/python/src/peer_info.cpp
Executable file
|
@ -0,0 +1,63 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/peer_info.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
void bind_peer_info()
|
||||
{
|
||||
scope pi = class_<peer_info>("peer_info")
|
||||
.def_readonly("flags", &peer_info::flags)
|
||||
.def_readonly("ip", &peer_info::ip)
|
||||
.def_readonly("up_speed", &peer_info::up_speed)
|
||||
.def_readonly("down_speed", &peer_info::down_speed)
|
||||
.def_readonly("payload_up_speed", &peer_info::payload_up_speed)
|
||||
.def_readonly("payload_down_speed", &peer_info::payload_down_speed)
|
||||
.def_readonly("total_download", &peer_info::total_download)
|
||||
.def_readonly("total_upload", &peer_info::total_upload)
|
||||
.def_readonly("pid", &peer_info::pid)
|
||||
.def_readonly("pieces", &peer_info::pieces)
|
||||
.def_readonly("upload_limit", &peer_info::upload_limit)
|
||||
.def_readonly("download_limit", &peer_info::download_limit)
|
||||
.def_readonly("load_balancing", &peer_info::load_balancing)
|
||||
.def_readonly("download_queue_length", &peer_info::download_queue_length)
|
||||
.def_readonly("upload_queue_length", &peer_info::upload_queue_length)
|
||||
.def_readonly("downloading_piece_index", &peer_info::downloading_piece_index)
|
||||
.def_readonly("downloading_block_index", &peer_info::downloading_block_index)
|
||||
.def_readonly("downloading_progress", &peer_info::downloading_progress)
|
||||
.def_readonly("downloading_total", &peer_info::downloading_total)
|
||||
.def_readonly("client", &peer_info::client)
|
||||
.def_readonly("connection_type", &peer_info::connection_type)
|
||||
.def_readonly("source", &peer_info::source)
|
||||
;
|
||||
|
||||
pi.attr("interesting") = (int)peer_info::interesting;
|
||||
pi.attr("choked") = (int)peer_info::choked;
|
||||
pi.attr("remote_interested") = (int)peer_info::remote_interested;
|
||||
pi.attr("remote_choked") = (int)peer_info::remote_choked;
|
||||
pi.attr("supports_extensions") = (int)peer_info::supports_extensions;
|
||||
pi.attr("local_connection") = (int)peer_info::local_connection;
|
||||
pi.attr("handshake") = (int)peer_info::handshake;
|
||||
pi.attr("connecting") = (int)peer_info::connecting;
|
||||
pi.attr("queued") = (int)peer_info::queued;
|
||||
pi.attr("on_parole") = (int)peer_info::on_parole;
|
||||
pi.attr("seed") = (int)peer_info::seed;
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted;
|
||||
pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted;
|
||||
#endif
|
||||
|
||||
pi.attr("standard_bittorrent") = 0;
|
||||
pi.attr("web_seed") = 1;
|
||||
|
||||
pi.attr("tracker") = 0x1;
|
||||
pi.attr("dht") = 0x2;
|
||||
pi.attr("pex") = 0x4;
|
||||
pi.attr("lsd") = 0x8;
|
||||
pi.attr("resume_data") = 0x10;
|
||||
}
|
||||
|
344
libtorrent/bindings/python/src/peer_plugin.cpp
Executable file
|
@ -0,0 +1,344 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/extensions.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/peer_request.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
|
||||
{
|
||||
void add_handshake(entry& e)
|
||||
{
|
||||
if (override f = this->get_override("add_handshake"))
|
||||
e = call<entry>(f.ptr(), e);
|
||||
else
|
||||
peer_plugin::add_handshake(e);
|
||||
}
|
||||
|
||||
void default_add_handshake(entry& e)
|
||||
{
|
||||
this->peer_plugin::add_handshake(e);
|
||||
}
|
||||
|
||||
bool on_handshake()
|
||||
{
|
||||
if (override f = this->get_override("on_handshake"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_handshake();
|
||||
}
|
||||
|
||||
bool default_on_handshake()
|
||||
{
|
||||
return this->peer_plugin::on_handshake();
|
||||
}
|
||||
|
||||
bool on_extension_handshake(entry const& e)
|
||||
{
|
||||
if (override f = this->get_override("on_extension_handshake"))
|
||||
return f(e);
|
||||
else
|
||||
return peer_plugin::on_extension_handshake(e);
|
||||
}
|
||||
|
||||
bool default_on_extension_handshake(entry const& e)
|
||||
{
|
||||
return this->peer_plugin::on_extension_handshake(e);
|
||||
}
|
||||
|
||||
bool on_choke()
|
||||
{
|
||||
if (override f = this->get_override("on_choke"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_choke();
|
||||
}
|
||||
|
||||
bool default_on_choke()
|
||||
{
|
||||
return this->peer_plugin::on_choke();
|
||||
}
|
||||
|
||||
bool on_unchoke()
|
||||
{
|
||||
if (override f = this->get_override("on_unchoke"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_unchoke();
|
||||
}
|
||||
|
||||
bool default_on_unchoke()
|
||||
{
|
||||
return this->peer_plugin::on_unchoke();
|
||||
}
|
||||
|
||||
bool on_interested()
|
||||
{
|
||||
if (override f = this->get_override("on_interested"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_interested();
|
||||
}
|
||||
|
||||
bool default_on_interested()
|
||||
{
|
||||
return this->peer_plugin::on_interested();
|
||||
}
|
||||
|
||||
bool on_not_interested()
|
||||
{
|
||||
if (override f = this->get_override("on_not_interested"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_not_interested();
|
||||
}
|
||||
|
||||
bool default_on_not_interested()
|
||||
{
|
||||
return this->peer_plugin::on_not_interested();
|
||||
}
|
||||
|
||||
bool on_have(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_have"))
|
||||
return f(index);
|
||||
else
|
||||
return peer_plugin::on_have(index);
|
||||
}
|
||||
|
||||
bool default_on_have(int index)
|
||||
{
|
||||
return this->peer_plugin::on_have(index);
|
||||
}
|
||||
|
||||
bool on_bitfield(std::vector<bool> const& bitfield)
|
||||
{
|
||||
if (override f = this->get_override("on_bitfield"))
|
||||
return f(bitfield);
|
||||
else
|
||||
return peer_plugin::on_bitfield(bitfield);
|
||||
}
|
||||
|
||||
bool default_on_bitfield(std::vector<bool> const& bitfield)
|
||||
{
|
||||
return this->peer_plugin::on_bitfield(bitfield);
|
||||
}
|
||||
|
||||
bool on_request(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("on_request"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::on_request(req);
|
||||
}
|
||||
|
||||
bool default_on_request(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::on_request(req);
|
||||
}
|
||||
|
||||
bool on_piece(peer_request const& piece, char const* data)
|
||||
{
|
||||
if (override f = this->get_override("on_piece"))
|
||||
return f(piece, data);
|
||||
else
|
||||
return peer_plugin::on_piece(piece, data);
|
||||
}
|
||||
|
||||
bool default_on_piece(peer_request const& piece, char const* data)
|
||||
{
|
||||
return this->peer_plugin::on_piece(piece, data);
|
||||
}
|
||||
|
||||
bool on_cancel(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("on_cancel"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::on_cancel(req);
|
||||
}
|
||||
|
||||
bool default_on_cancel(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::on_cancel(req);
|
||||
}
|
||||
|
||||
bool on_extended(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
if (override f = this->get_override("on_extended"))
|
||||
return f(length, msg, body);
|
||||
else
|
||||
return peer_plugin::on_extended(length, msg, body);
|
||||
}
|
||||
|
||||
bool default_on_extended(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
return this->peer_plugin::on_extended(length, msg, body);
|
||||
}
|
||||
|
||||
bool on_unknown_message(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
if (override f = this->get_override("on_unknown_message"))
|
||||
return f(length, msg, body);
|
||||
else
|
||||
return peer_plugin::on_unknown_message(length, msg, body);
|
||||
}
|
||||
|
||||
bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
return this->peer_plugin::on_unknown_message(length, msg, body);
|
||||
}
|
||||
|
||||
void on_piece_pass(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_piece_pass"))
|
||||
f(index);
|
||||
else
|
||||
peer_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void default_on_piece_pass(int index)
|
||||
{
|
||||
this->peer_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void on_piece_failed(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_piece_failed"))
|
||||
f(index);
|
||||
else
|
||||
peer_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void default_on_piece_failed(int index)
|
||||
{
|
||||
this->peer_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
if (override f = this->get_override("tick"))
|
||||
f();
|
||||
else
|
||||
peer_plugin::tick();
|
||||
}
|
||||
|
||||
void default_tick()
|
||||
{
|
||||
this->peer_plugin::tick();
|
||||
}
|
||||
|
||||
bool write_request(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("write_request"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::write_request(req);
|
||||
}
|
||||
|
||||
bool default_write_request(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::write_request(req);
|
||||
}
|
||||
};
|
||||
|
||||
object get_buffer()
|
||||
{
|
||||
static char const data[] = "foobar";
|
||||
return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_peer_plugin()
|
||||
{
|
||||
class_<
|
||||
peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
|
||||
>("peer_plugin")
|
||||
.def(
|
||||
"add_handshake"
|
||||
, &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
|
||||
)
|
||||
.def(
|
||||
"on_handshake"
|
||||
, &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
|
||||
)
|
||||
.def(
|
||||
"on_extension_handshake"
|
||||
, &peer_plugin::on_extension_handshake
|
||||
, &peer_plugin_wrap::default_on_extension_handshake
|
||||
)
|
||||
.def(
|
||||
"on_choke"
|
||||
, &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
|
||||
)
|
||||
.def(
|
||||
"on_unchoke"
|
||||
, &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
|
||||
)
|
||||
.def(
|
||||
"on_interested"
|
||||
, &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
|
||||
)
|
||||
.def(
|
||||
"on_not_interested"
|
||||
, &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
|
||||
)
|
||||
.def(
|
||||
"on_have"
|
||||
, &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
|
||||
)
|
||||
.def(
|
||||
"on_bitfield"
|
||||
, &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
|
||||
)
|
||||
.def(
|
||||
"on_request"
|
||||
, &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
|
||||
)
|
||||
.def(
|
||||
"on_piece"
|
||||
, &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
|
||||
)
|
||||
.def(
|
||||
"on_cancel"
|
||||
, &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
|
||||
)
|
||||
.def(
|
||||
"on_piece_pass"
|
||||
, &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
|
||||
)
|
||||
.def(
|
||||
"on_piece_failed"
|
||||
, &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
|
||||
)
|
||||
.def(
|
||||
"tick"
|
||||
, &peer_plugin::tick, &peer_plugin_wrap::default_tick
|
||||
)
|
||||
.def(
|
||||
"write_request"
|
||||
, &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
|
||||
)
|
||||
// These seem to make VC7.1 freeze. Needs special handling.
|
||||
|
||||
/*.def(
|
||||
"on_extended"
|
||||
, &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
|
||||
)
|
||||
.def(
|
||||
"on_unknown_message"
|
||||
, &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
|
||||
)*/
|
||||
;
|
||||
|
||||
def("get_buffer", &get_buffer);
|
||||
}
|
||||
|
214
libtorrent/bindings/python/src/session.cpp
Executable file
|
@ -0,0 +1,214 @@
|
|||
// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/torrent.hpp>
|
||||
#include <libtorrent/storage.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
extern char const* session_status_doc;
|
||||
extern char const* session_status_has_incoming_connections_doc;
|
||||
extern char const* session_status_upload_rate_doc;
|
||||
extern char const* session_status_download_rate_doc;
|
||||
extern char const* session_status_payload_upload_rate_doc;
|
||||
extern char const* session_status_payload_download_rate_doc;
|
||||
extern char const* session_status_total_download_doc;
|
||||
extern char const* session_status_total_upload_doc;
|
||||
extern char const* session_status_total_payload_download_doc;
|
||||
extern char const* session_status_total_payload_upload_doc;
|
||||
extern char const* session_status_num_peers_doc;
|
||||
extern char const* session_status_dht_nodes_doc;
|
||||
extern char const* session_status_cache_nodes_doc;
|
||||
extern char const* session_status_dht_torrents_doc;
|
||||
|
||||
extern char const* session_doc;
|
||||
extern char const* session_init_doc;
|
||||
extern char const* session_listen_on_doc;
|
||||
extern char const* session_is_listening_doc;
|
||||
extern char const* session_listen_port_doc;
|
||||
extern char const* session_status_m_doc;
|
||||
extern char const* session_start_dht_doc;
|
||||
extern char const* session_stop_dht_doc;
|
||||
extern char const* session_dht_state_doc;
|
||||
extern char const* session_add_torrent_doc;
|
||||
extern char const* session_remove_torrent_doc;
|
||||
extern char const* session_set_download_rate_limit_doc;
|
||||
extern char const* session_set_upload_rate_limit_doc;
|
||||
extern char const* session_set_max_uploads_doc;
|
||||
extern char const* session_set_max_connections_doc;
|
||||
extern char const* session_set_max_half_open_connections_doc;
|
||||
extern char const* session_set_settings_doc;
|
||||
extern char const* session_set_severity_level_doc;
|
||||
extern char const* session_pop_alert_doc;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool listen_on(session& s, int min_, int max_, char const* interface)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.listen_on(std::make_pair(min_, max_), interface);
|
||||
}
|
||||
|
||||
struct invoke_extension_factory
|
||||
{
|
||||
invoke_extension_factory(object const& callback)
|
||||
: cb(callback)
|
||||
{}
|
||||
|
||||
boost::shared_ptr<torrent_plugin> operator()(torrent* t)
|
||||
{
|
||||
lock_gil lock;
|
||||
return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
|
||||
}
|
||||
|
||||
object cb;
|
||||
};
|
||||
|
||||
void add_extension(session& s, object const& e)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.add_extension(invoke_extension_factory(e));
|
||||
}
|
||||
|
||||
torrent_handle add_torrent(session& s, torrent_info const& ti
|
||||
, boost::filesystem::path const& save, entry const& resume
|
||||
, bool compact, int block_size)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_torrent(ti, save, resume, compact, block_size
|
||||
, default_storage_constructor);
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_session()
|
||||
{
|
||||
class_<session_status>("session_status", session_status_doc)
|
||||
.def_readonly(
|
||||
"has_incoming_connections", &session_status::has_incoming_connections
|
||||
, session_status_has_incoming_connections_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"upload_rate", &session_status::upload_rate
|
||||
, session_status_upload_rate_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"download_rate", &session_status::download_rate
|
||||
, session_status_download_rate_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"payload_upload_rate", &session_status::payload_upload_rate
|
||||
, session_status_payload_upload_rate_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"payload_download_rate", &session_status::payload_download_rate
|
||||
, session_status_payload_download_rate_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_download", &session_status::total_download
|
||||
, session_status_total_download_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_upload", &session_status::total_upload
|
||||
, session_status_total_upload_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_payload_download", &session_status::total_payload_download
|
||||
, session_status_total_payload_download_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_payload_upload", &session_status::total_payload_upload
|
||||
, session_status_total_payload_upload_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"num_peers", &session_status::num_peers
|
||||
, session_status_num_peers_doc
|
||||
)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def_readonly(
|
||||
"dht_nodes", &session_status::dht_nodes
|
||||
, session_status_dht_nodes_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"dht_cache_nodes", &session_status::dht_node_cache
|
||||
, session_status_cache_nodes_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"dht_torrents", &session_status::dht_torrents
|
||||
, session_status_dht_torrents_doc
|
||||
)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<session, boost::noncopyable>("session", session_doc, no_init)
|
||||
.def(
|
||||
init<fingerprint>(arg("fingerprint")=fingerprint("LT",0,1,0,0), session_init_doc)
|
||||
)
|
||||
.def(
|
||||
"listen_on", &listen_on
|
||||
, (arg("min"), "max", arg("interface") = (char const*)0)
|
||||
, session_listen_on_doc
|
||||
)
|
||||
.def("is_listening", allow_threads(&session::is_listening), session_is_listening_doc)
|
||||
.def("listen_port", allow_threads(&session::listen_port), session_listen_port_doc)
|
||||
.def("status", allow_threads(&session::status), session_status_m_doc)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def("start_dht", allow_threads(&session::start_dht), session_start_dht_doc)
|
||||
.def("stop_dht", allow_threads(&session::stop_dht), session_stop_dht_doc)
|
||||
.def("dht_state", allow_threads(&session::dht_state), session_dht_state_doc)
|
||||
#endif
|
||||
.def(
|
||||
"add_torrent", &add_torrent
|
||||
, (
|
||||
arg("torrent_info"), "save_path", arg("resume_data") = entry()
|
||||
, arg("compact_mode") = true, arg("block_size") = 16 * 1024
|
||||
)
|
||||
, session_add_torrent_doc
|
||||
)
|
||||
.def("remove_torrent", allow_threads(&session::remove_torrent), session_remove_torrent_doc)
|
||||
.def(
|
||||
"set_download_rate_limit", allow_threads(&session::set_download_rate_limit)
|
||||
, session_set_download_rate_limit_doc
|
||||
)
|
||||
.def(
|
||||
"set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit)
|
||||
, session_set_upload_rate_limit_doc
|
||||
)
|
||||
.def(
|
||||
"set_max_uploads", allow_threads(&session::set_max_uploads)
|
||||
, session_set_max_uploads_doc
|
||||
)
|
||||
.def(
|
||||
"set_max_connections", allow_threads(&session::set_max_connections)
|
||||
, session_set_max_connections_doc
|
||||
)
|
||||
.def(
|
||||
"set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections)
|
||||
, session_set_max_half_open_connections_doc
|
||||
)
|
||||
.def("set_settings", allow_threads(&session::set_settings), session_set_settings_doc)
|
||||
.def(
|
||||
"set_severity_level", allow_threads(&session::set_severity_level)
|
||||
, session_set_severity_level_doc
|
||||
)
|
||||
.def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
|
||||
.def("add_extension", &add_extension)
|
||||
.def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
|
||||
.def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
|
||||
.def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
|
||||
#endif
|
||||
;
|
||||
|
||||
def("supports_sparse_files", &supports_sparse_files);
|
||||
|
||||
register_ptr_to_python<std::auto_ptr<alert> >();
|
||||
}
|
||||
|
77
libtorrent/bindings/python/src/session_settings.cpp
Executable file
|
@ -0,0 +1,77 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
void bind_session_settings()
|
||||
{
|
||||
class_<session_settings>("session_settings")
|
||||
.def_readwrite("user_agent", &session_settings::user_agent)
|
||||
.def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
|
||||
.def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
|
||||
.def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
|
||||
.def_readwrite("piece_timeout", &session_settings::piece_timeout)
|
||||
.def_readwrite("request_queue_time", &session_settings::request_queue_time)
|
||||
.def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
|
||||
.def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
|
||||
.def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
|
||||
.def_readwrite("peer_timeout", &session_settings::peer_timeout)
|
||||
.def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
|
||||
.def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
|
||||
.def_readwrite("file_pool_size", &session_settings::file_pool_size)
|
||||
.def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
|
||||
.def_readwrite("max_failcount", &session_settings::max_failcount)
|
||||
.def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
|
||||
.def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
|
||||
.def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
|
||||
.def_readwrite("connection_speed", &session_settings::connection_speed)
|
||||
.def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
|
||||
.def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
|
||||
.def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
|
||||
.def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
|
||||
#endif
|
||||
;
|
||||
|
||||
enum_<proxy_settings::proxy_type>("proxy_type")
|
||||
.value("none", proxy_settings::none)
|
||||
.value("socks4", proxy_settings::socks4)
|
||||
.value("socks5", proxy_settings::socks5)
|
||||
.value("socks5_pw", proxy_settings::socks5_pw)
|
||||
.value("http", proxy_settings::http)
|
||||
.value("http_pw", proxy_settings::http_pw)
|
||||
;
|
||||
scope ps = class_<proxy_settings>("proxy_settings")
|
||||
.def_readwrite("hostname", &proxy_settings::hostname)
|
||||
.def_readwrite("port", &proxy_settings::port)
|
||||
.def_readwrite("password", &proxy_settings::password)
|
||||
.def_readwrite("username", &proxy_settings::username)
|
||||
.def_readwrite("type", &proxy_settings::type)
|
||||
;
|
||||
|
||||
enum_<pe_settings::enc_policy>("enc_policy")
|
||||
.value("forced", pe_settings::forced)
|
||||
.value("enabled", pe_settings::enabled)
|
||||
.value("disabled", pe_settings::disabled)
|
||||
;
|
||||
|
||||
enum_<pe_settings::enc_level>("enc_level")
|
||||
.value("rc4", pe_settings::rc4)
|
||||
.value("plaintext", pe_settings::plaintext)
|
||||
;
|
||||
|
||||
scope pes = class_<pe_settings>("pe_settings")
|
||||
.def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
|
||||
.def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
|
||||
.def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
|
||||
.def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
|
||||
;
|
||||
|
||||
}
|
||||
|
15
libtorrent/bindings/python/src/torrent.cpp
Executable file
|
@ -0,0 +1,15 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/torrent.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
void bind_torrent()
|
||||
{
|
||||
class_<torrent, boost::noncopyable>("torrent", no_init);
|
||||
}
|
||||
|
163
libtorrent/bindings/python/src/torrent_handle.cpp
Executable file
|
@ -0,0 +1,163 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return i.trackers().begin();
|
||||
}
|
||||
|
||||
|
||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return i.trackers().end();
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
list file_progress(torrent_handle& handle)
|
||||
{
|
||||
std::vector<float> p;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
p.reserve(handle.get_torrent_info().num_files());
|
||||
handle.file_progress(p);
|
||||
}
|
||||
|
||||
list result;
|
||||
|
||||
for (std::vector<float>::iterator i(p.begin()), e(p.end()); i != e; ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
list get_peer_info(torrent_handle const& handle)
|
||||
{
|
||||
std::vector<peer_info> pi;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
handle.get_peer_info(pi);
|
||||
}
|
||||
|
||||
list result;
|
||||
|
||||
for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
|
||||
{
|
||||
result.append(*i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void replace_trackers(torrent_handle& info, object trackers)
|
||||
{
|
||||
object iter(trackers.attr("__iter__")());
|
||||
|
||||
std::vector<announce_entry> result;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
handle<> entry(allow_null(PyIter_Next(iter.ptr())));
|
||||
|
||||
if (entry == handle<>())
|
||||
break;
|
||||
|
||||
result.push_back(extract<announce_entry const&>(object(entry)));
|
||||
}
|
||||
|
||||
allow_threading_guard guard;
|
||||
info.replace_trackers(result);
|
||||
}
|
||||
|
||||
list get_download_queue(torrent_handle& handle)
|
||||
{
|
||||
list ret;
|
||||
|
||||
std::vector<partial_piece_info> downloading;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
handle.get_download_queue(downloading);
|
||||
}
|
||||
|
||||
for (std::vector<partial_piece_info>::iterator i = downloading.begin()
|
||||
, end(downloading.end()); i != end; ++i)
|
||||
{
|
||||
dict partial_piece;
|
||||
partial_piece["piece_index"] = i->piece_index;
|
||||
partial_piece["blocks_in_piece"] = i->blocks_in_piece;
|
||||
list block_list;
|
||||
for (int k = 0; k < i->blocks_in_piece; ++k)
|
||||
{
|
||||
dict block_info;
|
||||
block_info["state"] = i->blocks[k].state;
|
||||
block_info["num_downloads"] = i->blocks[k].num_downloads;
|
||||
// block_info["peer"] = i->info[k].peer;
|
||||
block_list.append(block_info);
|
||||
}
|
||||
partial_piece["blocks"] = block_list;
|
||||
|
||||
ret.append(partial_piece);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bind_torrent_handle()
|
||||
{
|
||||
void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;
|
||||
void (torrent_handle::*force_reannounce1)(boost::posix_time::time_duration) const
|
||||
= &torrent_handle::force_reannounce;
|
||||
|
||||
return_value_policy<copy_const_reference> copy;
|
||||
|
||||
#define _ allow_threads
|
||||
|
||||
class_<torrent_handle>("torrent_handle")
|
||||
.def("status", _(&torrent_handle::status))
|
||||
.def("torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
|
||||
.def("is_valid", _(&torrent_handle::is_valid))
|
||||
.def("write_resume_data", _(&torrent_handle::write_resume_data))
|
||||
.def("force_reannounce", _(force_reannounce0))
|
||||
.def("force_reannounce", _(force_reannounce1))
|
||||
.def("set_tracker_login", _(&torrent_handle::set_tracker_login))
|
||||
.def("add_url_seed", _(&torrent_handle::add_url_seed))
|
||||
.def("set_ratio", _(&torrent_handle::set_ratio))
|
||||
.def("set_max_uploads", _(&torrent_handle::set_max_uploads))
|
||||
.def("set_max_connections", _(&torrent_handle::set_max_connections))
|
||||
.def("set_upload_limit", _(&torrent_handle::set_upload_limit))
|
||||
.def("set_download_limit", _(&torrent_handle::set_download_limit))
|
||||
.def("set_sequenced_download_threshold", _(&torrent_handle::set_sequenced_download_threshold))
|
||||
.def("pause", _(&torrent_handle::pause))
|
||||
.def("resume", _(&torrent_handle::resume))
|
||||
.def("is_paused", _(&torrent_handle::is_paused))
|
||||
.def("is_seed", _(&torrent_handle::is_seed))
|
||||
.def("filter_piece", _(&torrent_handle::filter_piece))
|
||||
.def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
|
||||
.def("has_metadata", _(&torrent_handle::has_metadata))
|
||||
.def("save_path", _(&torrent_handle::save_path))
|
||||
.def("move_storage", _(&torrent_handle::move_storage))
|
||||
.def("info_hash", _(&torrent_handle::info_hash), copy)
|
||||
.def("file_progress", file_progress)
|
||||
.def("trackers", range(begin_trackers, end_trackers))
|
||||
.def("replace_trackers", replace_trackers)
|
||||
.def("get_peer_info", get_peer_info)
|
||||
.def("get_download_queue", get_download_queue)
|
||||
;
|
||||
}
|
||||
|
103
libtorrent/bindings/python/src/torrent_info.cpp
Executable file
|
@ -0,0 +1,103 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/torrent_info.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().begin();
|
||||
}
|
||||
|
||||
|
||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().end();
|
||||
}
|
||||
|
||||
void add_node(torrent_info& ti, char const* hostname, int port)
|
||||
{
|
||||
ti.add_node(std::make_pair(hostname, port));
|
||||
}
|
||||
|
||||
list nodes(torrent_info const& ti)
|
||||
{
|
||||
list result;
|
||||
|
||||
typedef std::vector<std::pair<std::string, int> > list_type;
|
||||
|
||||
for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
|
||||
{
|
||||
result.append(make_tuple(i->first, i->second));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_torrent_info()
|
||||
{
|
||||
return_value_policy<copy_const_reference> copy;
|
||||
|
||||
class_<torrent_info>("torrent_info")
|
||||
.def(init<entry const&>())
|
||||
.def(init<sha1_hash const&>())
|
||||
|
||||
.def("create_torrent", &torrent_info::create_torrent)
|
||||
.def("set_comment", &torrent_info::set_comment)
|
||||
.def("set_piece_size", &torrent_info::set_piece_size)
|
||||
.def("set_creator", &torrent_info::set_creator)
|
||||
.def("set_hash", &torrent_info::set_hash)
|
||||
.def("add_tracker", &torrent_info::add_tracker, (arg("url"), arg("tier")=0))
|
||||
.def("add_file", &torrent_info::add_file)
|
||||
.def("add_url_seed", &torrent_info::add_url_seed)
|
||||
|
||||
.def("name", &torrent_info::name, copy)
|
||||
.def("comment", &torrent_info::comment, copy)
|
||||
.def("creator", &torrent_info::creator, copy)
|
||||
.def("total_size", &torrent_info::total_size)
|
||||
.def("piece_length", &torrent_info::piece_length)
|
||||
.def("num_pieces", &torrent_info::num_pieces)
|
||||
.def("info_hash", &torrent_info::info_hash, copy)
|
||||
|
||||
.def("hash_for_piece", &torrent_info::hash_for_piece, copy)
|
||||
.def("piece_size", &torrent_info::piece_size)
|
||||
|
||||
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
||||
.def("files", range(&torrent_info::begin_files, &torrent_info::end_files))
|
||||
|
||||
.def("priv", &torrent_info::priv)
|
||||
.def("set_priv", &torrent_info::set_priv)
|
||||
.def("trackers", range(begin_trackers, end_trackers))
|
||||
|
||||
.def("creation_date", &torrent_info::creation_date)
|
||||
|
||||
.def("add_node", &add_node)
|
||||
.def("nodes", &nodes)
|
||||
;
|
||||
|
||||
class_<file_entry>("file_entry")
|
||||
.add_property(
|
||||
"path"
|
||||
, make_getter(
|
||||
&file_entry::path, return_value_policy<copy_non_const_reference>()
|
||||
)
|
||||
)
|
||||
.def_readonly("offset", &file_entry::offset)
|
||||
.def_readonly("size", &file_entry::size)
|
||||
;
|
||||
|
||||
class_<announce_entry>("announce_entry", init<std::string const&>())
|
||||
.def_readwrite("url", &announce_entry::url)
|
||||
.def_readwrite("tier", &announce_entry::tier)
|
||||
;
|
||||
}
|
||||
|
107
libtorrent/bindings/python/src/torrent_status.cpp
Executable file
|
@ -0,0 +1,107 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
object pieces(torrent_status const& s)
|
||||
{
|
||||
list result;
|
||||
|
||||
for (std::vector<bool>::const_iterator i(s.pieces->begin()), e(s.pieces->end()); i != e; ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern char const* torrent_status_doc;
|
||||
extern char const* torrent_status_state_doc;
|
||||
extern char const* torrent_status_paused_doc;
|
||||
extern char const* torrent_status_progress_doc;
|
||||
extern char const* torrent_status_next_announce_doc;
|
||||
extern char const* torrent_status_announce_interval_doc;
|
||||
extern char const* torrent_status_current_tracker_doc;
|
||||
extern char const* torrent_status_total_download_doc;
|
||||
extern char const* torrent_status_total_upload_doc;
|
||||
extern char const* torrent_status_total_payload_download_doc;
|
||||
extern char const* torrent_status_total_payload_upload_doc;
|
||||
extern char const* torrent_status_total_failed_bytes_doc;
|
||||
|
||||
void bind_torrent_status()
|
||||
{
|
||||
scope status = class_<torrent_status>("torrent_status", torrent_status_doc)
|
||||
.def_readonly("state", &torrent_status::state, torrent_status_state_doc)
|
||||
.def_readonly("paused", &torrent_status::paused, torrent_status_paused_doc)
|
||||
.def_readonly("progress", &torrent_status::progress, torrent_status_progress_doc)
|
||||
.add_property(
|
||||
"next_announce"
|
||||
, make_getter(
|
||||
&torrent_status::next_announce, return_value_policy<return_by_value>()
|
||||
)
|
||||
, torrent_status_next_announce_doc
|
||||
)
|
||||
.add_property(
|
||||
"announce_interval"
|
||||
, make_getter(
|
||||
&torrent_status::announce_interval, return_value_policy<return_by_value>()
|
||||
)
|
||||
, torrent_status_announce_interval_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"current_tracker", &torrent_status::current_tracker
|
||||
, torrent_status_current_tracker_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_download", &torrent_status::total_download
|
||||
, torrent_status_total_download_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_upload", &torrent_status::total_upload
|
||||
, torrent_status_total_upload_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_payload_download", &torrent_status::total_payload_download
|
||||
, torrent_status_total_payload_download_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_payload_upload", &torrent_status::total_payload_upload
|
||||
, torrent_status_total_payload_upload_doc
|
||||
)
|
||||
.def_readonly(
|
||||
"total_failed_bytes", &torrent_status::total_failed_bytes
|
||||
, torrent_status_total_failed_bytes_doc
|
||||
)
|
||||
.def_readonly("total_redundant_bytes", &torrent_status::total_redundant_bytes)
|
||||
.def_readonly("download_rate", &torrent_status::download_rate)
|
||||
.def_readonly("upload_rate", &torrent_status::upload_rate)
|
||||
.def_readonly("download_payload_rate", &torrent_status::download_payload_rate)
|
||||
.def_readonly("upload_payload_rate", &torrent_status::upload_payload_rate)
|
||||
.def_readonly("num_peers", &torrent_status::num_peers)
|
||||
.def_readonly("num_complete", &torrent_status::num_complete)
|
||||
.def_readonly("num_incomplete", &torrent_status::num_incomplete)
|
||||
.add_property("pieces", pieces)
|
||||
.def_readonly("num_pieces", &torrent_status::num_pieces)
|
||||
.def_readonly("total_done", &torrent_status::total_done)
|
||||
.def_readonly("total_wanted_done", &torrent_status::total_wanted_done)
|
||||
.def_readonly("total_wanted", &torrent_status::total_wanted)
|
||||
.def_readonly("num_seeds", &torrent_status::num_seeds)
|
||||
.def_readonly("distributed_copies", &torrent_status::distributed_copies)
|
||||
.def_readonly("block_size", &torrent_status::block_size)
|
||||
;
|
||||
|
||||
enum_<torrent_status::state_t>("states")
|
||||
.value("queued_for_checking", torrent_status::queued_for_checking)
|
||||
.value("checking_files", torrent_status::checking_files)
|
||||
.value("connecting_to_tracker", torrent_status::connecting_to_tracker)
|
||||
.value("downloading", torrent_status::downloading)
|
||||
.value("finished", torrent_status::finished)
|
||||
.value("seeding", torrent_status::seeding)
|
||||
.value("allocating", torrent_status::allocating)
|
||||
.export_values()
|
||||
;
|
||||
}
|
||||
|
37
libtorrent/bindings/python/src/utility.cpp
Executable file
|
@ -0,0 +1,37 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/identify_client.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
object client_fingerprint_(peer_id const& id)
|
||||
{
|
||||
boost::optional<fingerprint> result = client_fingerprint(id);
|
||||
return result ? object(*result) : object();
|
||||
}
|
||||
|
||||
entry bdecode_(std::string const& data)
|
||||
{
|
||||
return bdecode(data.begin(), data.end());
|
||||
}
|
||||
|
||||
std::string bencode_(entry const& e)
|
||||
{
|
||||
std::string result;
|
||||
bencode(std::back_inserter(result), e);
|
||||
return result;
|
||||
}
|
||||
|
||||
void bind_utility()
|
||||
{
|
||||
def("identify_client", &libtorrent::identify_client);
|
||||
def("client_fingerprint", &client_fingerprint_);
|
||||
def("bdecode", &bdecode_);
|
||||
def("bencode", &bencode_);
|
||||
}
|
||||
|
16
libtorrent/bindings/python/src/version.cpp
Executable file
|
@ -0,0 +1,16 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/version.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
void bind_version()
|
||||
{
|
||||
scope().attr("version") = LIBTORRENT_VERSION;
|
||||
scope().attr("version_major") = LIBTORRENT_VERSION_MAJOR;
|
||||
scope().attr("version_minor") = LIBTORRENT_VERSION_MINOR;
|
||||
}
|
||||
|
232
libtorrent/include/Makefile.am
Normal file
|
@ -0,0 +1,232 @@
|
|||
nobase_include_HEADERS = libtorrent/alert.hpp \
|
||||
libtorrent/alert_types.hpp \
|
||||
libtorrent/allocate_resources.hpp \
|
||||
libtorrent/bandwidth_manager.hpp \
|
||||
libtorrent/bencode.hpp \
|
||||
libtorrent/buffer.hpp \
|
||||
libtorrent/connection_queue.hpp \
|
||||
libtorrent/config.hpp \
|
||||
libtorrent/debug.hpp \
|
||||
libtorrent/disk_io_thread.hpp \
|
||||
libtorrent/entry.hpp \
|
||||
libtorrent/escape_string.hpp \
|
||||
libtorrent/extensions.hpp \
|
||||
libtorrent/file.hpp \
|
||||
libtorrent/file_pool.hpp \
|
||||
libtorrent/fingerprint.hpp \
|
||||
libtorrent/hasher.hpp \
|
||||
libtorrent/http_connection.hpp \
|
||||
libtorrent/http_stream.hpp \
|
||||
libtorrent/http_tracker_connection.hpp \
|
||||
libtorrent/identify_client.hpp \
|
||||
libtorrent/instantiate_connection.hpp \
|
||||
libtorrent/intrusive_ptr_base.hpp \
|
||||
libtorrent/invariant_check.hpp \
|
||||
libtorrent/io.hpp \
|
||||
libtorrent/ip_filter.hpp \
|
||||
libtorrent/lsd.hpp \
|
||||
libtorrent/peer.hpp \
|
||||
libtorrent/peer_connection.hpp \
|
||||
libtorrent/bt_peer_connection.hpp \
|
||||
libtorrent/web_peer_connection.hpp \
|
||||
libtorrent/pe_crypto.hpp \
|
||||
libtorrent/natpmp.hpp \
|
||||
libtorrent/pch.hpp \
|
||||
libtorrent/peer_id.hpp \
|
||||
libtorrent/peer_info.hpp \
|
||||
libtorrent/peer_request.hpp \
|
||||
libtorrent/piece_block_progress.hpp \
|
||||
libtorrent/piece_picker.hpp \
|
||||
libtorrent/policy.hpp \
|
||||
libtorrent/proxy_base.hpp \
|
||||
libtorrent/random_sample.hpp \
|
||||
libtorrent/resource_request.hpp \
|
||||
libtorrent/session.hpp \
|
||||
libtorrent/session_settings.hpp \
|
||||
libtorrent/session_status.hpp \
|
||||
libtorrent/size_type.hpp \
|
||||
libtorrent/socket.hpp \
|
||||
libtorrent/socket_type.hpp \
|
||||
libtorrent/socks4_stream.hpp \
|
||||
libtorrent/socks5_stream.hpp \
|
||||
libtorrent/stat.hpp \
|
||||
libtorrent/storage.hpp \
|
||||
libtorrent/time.hpp \
|
||||
libtorrent/torrent.hpp \
|
||||
libtorrent/torrent_handle.hpp \
|
||||
libtorrent/torrent_info.hpp \
|
||||
libtorrent/tracker_manager.hpp \
|
||||
libtorrent/udp_tracker_connection.hpp \
|
||||
libtorrent/utf8.hpp \
|
||||
libtorrent/xml_parse.hpp \
|
||||
libtorrent/variant_stream.hpp \
|
||||
libtorrent/version.hpp \
|
||||
libtorrent/time.hpp \
|
||||
libtorrent/aux_/allocate_resources_impl.hpp \
|
||||
libtorrent/aux_/session_impl.hpp \
|
||||
libtorrent/extensions/metadata_transfer.hpp \
|
||||
libtorrent/extensions/ut_pex.hpp \
|
||||
libtorrent/extensions/logger.hpp \
|
||||
\
|
||||
libtorrent/kademlia/closest_nodes.hpp \
|
||||
libtorrent/kademlia/dht_tracker.hpp \
|
||||
libtorrent/kademlia/find_data.hpp \
|
||||
libtorrent/kademlia/logging.hpp \
|
||||
libtorrent/kademlia/msg.hpp \
|
||||
libtorrent/kademlia/node.hpp \
|
||||
libtorrent/kademlia/node_entry.hpp \
|
||||
libtorrent/kademlia/node_id.hpp \
|
||||
libtorrent/kademlia/observer.hpp \
|
||||
libtorrent/kademlia/packet_iterator.hpp \
|
||||
libtorrent/kademlia/refresh.hpp \
|
||||
libtorrent/kademlia/routing_table.hpp \
|
||||
libtorrent/kademlia/rpc_manager.hpp \
|
||||
libtorrent/kademlia/traversal_algorithm.hpp \
|
||||
\
|
||||
libtorrent/asio.hpp \
|
||||
libtorrent/asio/basic_datagram_socket.hpp \
|
||||
libtorrent/asio/basic_deadline_timer.hpp \
|
||||
libtorrent/asio/basic_io_object.hpp \
|
||||
libtorrent/asio/basic_socket.hpp \
|
||||
libtorrent/asio/basic_socket_acceptor.hpp \
|
||||
libtorrent/asio/basic_socket_iostream.hpp \
|
||||
libtorrent/asio/basic_socket_streambuf.hpp \
|
||||
libtorrent/asio/basic_stream_socket.hpp \
|
||||
libtorrent/asio/basic_streambuf.hpp \
|
||||
libtorrent/asio/buffer.hpp \
|
||||
libtorrent/asio/buffered_read_stream.hpp \
|
||||
libtorrent/asio/buffered_read_stream_fwd.hpp \
|
||||
libtorrent/asio/buffered_stream.hpp \
|
||||
libtorrent/asio/buffered_stream_fwd.hpp \
|
||||
libtorrent/asio/buffered_write_stream.hpp \
|
||||
libtorrent/asio/buffered_write_stream_fwd.hpp \
|
||||
libtorrent/asio/completion_condition.hpp \
|
||||
libtorrent/asio/datagram_socket_service.hpp \
|
||||
libtorrent/asio/deadline_timer.hpp \
|
||||
libtorrent/asio/deadline_timer_service.hpp \
|
||||
libtorrent/asio/detail/bind_handler.hpp \
|
||||
libtorrent/asio/detail/buffer_resize_guard.hpp \
|
||||
libtorrent/asio/detail/buffered_stream_storage.hpp \
|
||||
libtorrent/asio/detail/call_stack.hpp \
|
||||
libtorrent/asio/detail/const_buffers_iterator.hpp \
|
||||
libtorrent/asio/detail/consuming_buffers.hpp \
|
||||
libtorrent/asio/detail/deadline_timer_service.hpp \
|
||||
libtorrent/asio/detail/epoll_reactor.hpp \
|
||||
libtorrent/asio/detail/epoll_reactor_fwd.hpp \
|
||||
libtorrent/asio/detail/event.hpp \
|
||||
libtorrent/asio/detail/fd_set_adapter.hpp \
|
||||
libtorrent/asio/detail/handler_alloc_helpers.hpp \
|
||||
libtorrent/asio/detail/handler_invoke_helpers.hpp \
|
||||
libtorrent/asio/detail/hash_map.hpp \
|
||||
libtorrent/asio/detail/io_control.hpp \
|
||||
libtorrent/asio/detail/kqueue_reactor.hpp \
|
||||
libtorrent/asio/detail/kqueue_reactor_fwd.hpp \
|
||||
libtorrent/asio/detail/local_free_on_block_exit.hpp \
|
||||
libtorrent/asio/detail/mutex.hpp \
|
||||
libtorrent/asio/detail/noncopyable.hpp \
|
||||
libtorrent/asio/detail/null_event.hpp \
|
||||
libtorrent/asio/detail/null_mutex.hpp \
|
||||
libtorrent/asio/detail/null_signal_blocker.hpp \
|
||||
libtorrent/asio/detail/null_thread.hpp \
|
||||
libtorrent/asio/detail/null_tss_ptr.hpp \
|
||||
libtorrent/asio/detail/old_win_sdk_compat.hpp \
|
||||
libtorrent/asio/detail/pipe_select_interrupter.hpp \
|
||||
libtorrent/asio/detail/pop_options.hpp \
|
||||
libtorrent/asio/detail/posix_event.hpp \
|
||||
libtorrent/asio/detail/posix_fd_set_adapter.hpp \
|
||||
libtorrent/asio/detail/posix_mutex.hpp \
|
||||
libtorrent/asio/detail/posix_signal_blocker.hpp \
|
||||
libtorrent/asio/detail/posix_thread.hpp \
|
||||
libtorrent/asio/detail/posix_tss_ptr.hpp \
|
||||
libtorrent/asio/detail/push_options.hpp \
|
||||
libtorrent/asio/detail/reactive_socket_service.hpp \
|
||||
libtorrent/asio/detail/reactor_op_queue.hpp \
|
||||
libtorrent/asio/detail/resolver_service.hpp \
|
||||
libtorrent/asio/detail/scoped_lock.hpp \
|
||||
libtorrent/asio/detail/select_interrupter.hpp \
|
||||
libtorrent/asio/detail/select_reactor.hpp \
|
||||
libtorrent/asio/detail/select_reactor_fwd.hpp \
|
||||
libtorrent/asio/detail/service_registry.hpp \
|
||||
libtorrent/asio/detail/service_registry_fwd.hpp \
|
||||
libtorrent/asio/detail/service_base.hpp \
|
||||
libtorrent/asio/detail/service_id.hpp \
|
||||
libtorrent/asio/detail/signal_blocker.hpp \
|
||||
libtorrent/asio/detail/signal_init.hpp \
|
||||
libtorrent/asio/detail/socket_holder.hpp \
|
||||
libtorrent/asio/detail/socket_ops.hpp \
|
||||
libtorrent/asio/detail/socket_option.hpp \
|
||||
libtorrent/asio/detail/socket_select_interrupter.hpp \
|
||||
libtorrent/asio/detail/socket_types.hpp \
|
||||
libtorrent/asio/detail/strand_service.hpp \
|
||||
libtorrent/asio/detail/task_io_service.hpp \
|
||||
libtorrent/asio/detail/task_io_service_fwd.hpp \
|
||||
libtorrent/asio/detail/thread.hpp \
|
||||
libtorrent/asio/detail/throw_error.hpp \
|
||||
libtorrent/asio/detail/timer_queue.hpp \
|
||||
libtorrent/asio/detail/timer_queue_base.hpp \
|
||||
libtorrent/asio/detail/tss_ptr.hpp \
|
||||
libtorrent/asio/detail/win_event.hpp \
|
||||
libtorrent/asio/detail/win_fd_set_adapter.hpp \
|
||||
libtorrent/asio/detail/win_iocp_io_service.hpp \
|
||||
libtorrent/asio/detail/win_iocp_io_service_fwd.hpp \
|
||||
libtorrent/asio/detail/win_iocp_operation.hpp \
|
||||
libtorrent/asio/detail/win_iocp_socket_service.hpp \
|
||||
libtorrent/asio/detail/win_mutex.hpp \
|
||||
libtorrent/asio/detail/win_signal_blocker.hpp \
|
||||
libtorrent/asio/detail/win_thread.hpp \
|
||||
libtorrent/asio/detail/win_tss_ptr.hpp \
|
||||
libtorrent/asio/detail/winsock_init.hpp \
|
||||
libtorrent/asio/detail/wrapped_handler.hpp \
|
||||
libtorrent/asio/error.hpp \
|
||||
libtorrent/asio/error_code.hpp \
|
||||
libtorrent/asio/handler_alloc_hook.hpp \
|
||||
libtorrent/asio/handler_invoke_hook.hpp \
|
||||
libtorrent/asio/impl/error_code.ipp \
|
||||
libtorrent/asio/impl/io_service.ipp \
|
||||
libtorrent/asio/impl/read.ipp \
|
||||
libtorrent/asio/impl/read_until.ipp \
|
||||
libtorrent/asio/impl/write.ipp \
|
||||
libtorrent/asio/io_service.hpp \
|
||||
libtorrent/asio/ip/address.hpp \
|
||||
libtorrent/asio/ip/address_v4.hpp \
|
||||
libtorrent/asio/ip/address_v6.hpp \
|
||||
libtorrent/asio/ip/basic_endpoint.hpp \
|
||||
libtorrent/asio/ip/basic_resolver.hpp \
|
||||
libtorrent/asio/ip/basic_resolver_entry.hpp \
|
||||
libtorrent/asio/ip/basic_resolver_iterator.hpp \
|
||||
libtorrent/asio/ip/basic_resolver_query.hpp \
|
||||
libtorrent/asio/ip/detail/socket_option.hpp \
|
||||
libtorrent/asio/ip/host_name.hpp \
|
||||
libtorrent/asio/ip/multicast.hpp \
|
||||
libtorrent/asio/ip/resolver_query_base.hpp \
|
||||
libtorrent/asio/ip/resolver_service.hpp \
|
||||
libtorrent/asio/ip/tcp.hpp \
|
||||
libtorrent/asio/ip/udp.hpp \
|
||||
libtorrent/asio/is_read_buffered.hpp \
|
||||
libtorrent/asio/is_write_buffered.hpp \
|
||||
libtorrent/asio/placeholders.hpp \
|
||||
libtorrent/asio/read.hpp \
|
||||
libtorrent/asio/read_until.hpp \
|
||||
libtorrent/asio/socket_acceptor_service.hpp \
|
||||
libtorrent/asio/socket_base.hpp \
|
||||
libtorrent/asio/ssl/basic_context.hpp \
|
||||
libtorrent/asio/ssl/context.hpp \
|
||||
libtorrent/asio/ssl/context_base.hpp \
|
||||
libtorrent/asio/ssl/context_service.hpp \
|
||||
libtorrent/asio/ssl/detail/openssl_context_service.hpp \
|
||||
libtorrent/asio/ssl/detail/openssl_init.hpp \
|
||||
libtorrent/asio/ssl/detail/openssl_operation.hpp \
|
||||
libtorrent/asio/ssl/detail/openssl_stream_service.hpp \
|
||||
libtorrent/asio/ssl/detail/openssl_types.hpp \
|
||||
libtorrent/asio/ssl/stream.hpp \
|
||||
libtorrent/asio/ssl/stream_base.hpp \
|
||||
libtorrent/asio/ssl/stream_service.hpp \
|
||||
libtorrent/asio/ssl.hpp \
|
||||
libtorrent/asio/strand.hpp \
|
||||
libtorrent/asio/stream_socket_service.hpp \
|
||||
libtorrent/asio/streambuf.hpp \
|
||||
libtorrent/asio/system_error.hpp \
|
||||
libtorrent/asio/thread.hpp \
|
||||
libtorrent/asio/time_traits.hpp \
|
||||
libtorrent/asio/write.hpp
|
||||
|
74
libtorrent/include/asio.hpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// asio.hpp
|
||||
// ~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_HPP
|
||||
#define ASIO_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/basic_datagram_socket.hpp"
|
||||
#include "asio/basic_deadline_timer.hpp"
|
||||
#include "asio/basic_io_object.hpp"
|
||||
#include "asio/basic_socket_acceptor.hpp"
|
||||
#include "asio/basic_socket_iostream.hpp"
|
||||
#include "asio/basic_socket_streambuf.hpp"
|
||||
#include "asio/basic_stream_socket.hpp"
|
||||
#include "asio/basic_streambuf.hpp"
|
||||
#include "asio/buffer.hpp"
|
||||
#include "asio/buffered_read_stream_fwd.hpp"
|
||||
#include "asio/buffered_read_stream.hpp"
|
||||
#include "asio/buffered_stream_fwd.hpp"
|
||||
#include "asio/buffered_stream.hpp"
|
||||
#include "asio/buffered_write_stream_fwd.hpp"
|
||||
#include "asio/buffered_write_stream.hpp"
|
||||
#include "asio/completion_condition.hpp"
|
||||
#include "asio/datagram_socket_service.hpp"
|
||||
#include "asio/deadline_timer_service.hpp"
|
||||
#include "asio/deadline_timer.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/error_code.hpp"
|
||||
#include "asio/handler_alloc_hook.hpp"
|
||||
#include "asio/handler_invoke_hook.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/ip/address.hpp"
|
||||
#include "asio/ip/address_v4.hpp"
|
||||
#include "asio/ip/address_v6.hpp"
|
||||
#include "asio/ip/basic_endpoint.hpp"
|
||||
#include "asio/ip/basic_resolver.hpp"
|
||||
#include "asio/ip/basic_resolver_entry.hpp"
|
||||
#include "asio/ip/basic_resolver_iterator.hpp"
|
||||
#include "asio/ip/basic_resolver_query.hpp"
|
||||
#include "asio/ip/host_name.hpp"
|
||||
#include "asio/ip/multicast.hpp"
|
||||
#include "asio/ip/resolver_query_base.hpp"
|
||||
#include "asio/ip/resolver_service.hpp"
|
||||
#include "asio/ip/tcp.hpp"
|
||||
#include "asio/ip/udp.hpp"
|
||||
#include "asio/ip/unicast.hpp"
|
||||
#include "asio/ip/v6_only.hpp"
|
||||
#include "asio/is_read_buffered.hpp"
|
||||
#include "asio/is_write_buffered.hpp"
|
||||
#include "asio/placeholders.hpp"
|
||||
#include "asio/read.hpp"
|
||||
#include "asio/read_until.hpp"
|
||||
#include "asio/socket_acceptor_service.hpp"
|
||||
#include "asio/socket_base.hpp"
|
||||
#include "asio/strand.hpp"
|
||||
#include "asio/stream_socket_service.hpp"
|
||||
#include "asio/streambuf.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/thread.hpp"
|
||||
#include "asio/time_traits.hpp"
|
||||
#include "asio/version.hpp"
|
||||
#include "asio/write.hpp"
|
||||
|
||||
#endif // ASIO_HPP
|
45
libtorrent/include/asio/CVS/Entries
Normal file
|
@ -0,0 +1,45 @@
|
|||
/basic_datagram_socket.hpp/1.40/Thu Jan 4 05:44:43 2007//
|
||||
/basic_deadline_timer.hpp/1.23/Sun May 20 00:49:02 2007//
|
||||
/basic_io_object.hpp/1.8/Thu Jan 4 05:44:43 2007//
|
||||
/basic_socket.hpp/1.16/Mon Jan 8 22:12:45 2007//
|
||||
/basic_socket_acceptor.hpp/1.58/Fri Feb 9 05:47:48 2007//
|
||||
/basic_socket_iostream.hpp/1.8/Thu Jan 18 11:41:36 2007//
|
||||
/basic_socket_streambuf.hpp/1.6/Thu Jan 18 11:41:36 2007//
|
||||
/basic_stream_socket.hpp/1.69/Mon Jan 8 22:12:45 2007//
|
||||
/basic_streambuf.hpp/1.12/Thu Jan 4 10:23:31 2007//
|
||||
/buffer.hpp/1.23/Thu Jun 21 14:03:36 2007//
|
||||
/buffered_read_stream.hpp/1.17/Thu Jan 4 05:44:43 2007//
|
||||
/buffered_read_stream_fwd.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
||||
/buffered_stream.hpp/1.32/Thu Jan 4 05:44:43 2007//
|
||||
/buffered_stream_fwd.hpp/1.9/Thu Jan 4 05:44:43 2007//
|
||||
/buffered_write_stream.hpp/1.17/Thu Jan 4 05:44:43 2007//
|
||||
/buffered_write_stream_fwd.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
||||
/completion_condition.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
||||
/datagram_socket_service.hpp/1.34/Mon Jan 8 22:12:45 2007//
|
||||
/deadline_timer.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
||||
/deadline_timer_service.hpp/1.29/Mon Jan 8 02:47:13 2007//
|
||||
/error.hpp/1.39/Mon Jan 8 22:12:45 2007//
|
||||
/error_code.hpp/1.4/Mon Jan 8 22:12:45 2007//
|
||||
/handler_alloc_hook.hpp/1.11/Thu Jan 4 05:44:43 2007//
|
||||
/handler_invoke_hook.hpp/1.3/Thu Jan 4 05:44:43 2007//
|
||||
/io_service.hpp/1.24/Sun May 20 00:49:02 2007//
|
||||
/is_read_buffered.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
||||
/is_write_buffered.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
||||
/placeholders.hpp/1.10/Thu Jan 4 05:44:43 2007//
|
||||
/read.hpp/1.22/Thu Jan 4 05:44:43 2007//
|
||||
/read_until.hpp/1.8/Thu Jan 4 05:44:44 2007//
|
||||
/socket_acceptor_service.hpp/1.34/Fri Feb 9 05:47:48 2007//
|
||||
/socket_base.hpp/1.23/Mon Jan 8 23:45:36 2007//
|
||||
/ssl.hpp/1.4/Thu Jan 4 05:44:44 2007//
|
||||
/strand.hpp/1.6/Tue May 8 13:13:55 2007//
|
||||
/stream_socket_service.hpp/1.35/Mon Jan 8 22:12:46 2007//
|
||||
/streambuf.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/system_error.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/thread.hpp/1.15/Thu Jan 4 05:44:44 2007//
|
||||
/time_traits.hpp/1.9/Thu Jan 4 05:44:44 2007//
|
||||
/version.hpp/1.1/Tue May 8 12:17:36 2007//
|
||||
/write.hpp/1.21/Thu Jan 4 05:44:44 2007//
|
||||
D/detail////
|
||||
D/impl////
|
||||
D/ip////
|
||||
D/ssl////
|
1
libtorrent/include/asio/CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
asio/include/asio
|
1
libtorrent/include/asio/CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
803
libtorrent/include/asio/basic_datagram_socket.hpp
Normal file
|
@ -0,0 +1,803 @@
|
|||
//
|
||||
// basic_datagram_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_DATAGRAM_SOCKET_HPP
|
||||
#define ASIO_BASIC_DATAGRAM_SOCKET_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_socket.hpp"
|
||||
#include "asio/datagram_socket_service.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Provides datagram-oriented socket functionality.
|
||||
/**
|
||||
* The basic_datagram_socket class template provides asynchronous and blocking
|
||||
* datagram-oriented socket functionality.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename DatagramSocketService = datagram_socket_service<Protocol> >
|
||||
class basic_datagram_socket
|
||||
: public basic_socket<Protocol, DatagramSocketService>
|
||||
{
|
||||
public:
|
||||
/// The native representation of a socket.
|
||||
typedef typename DatagramSocketService::native_type native_type;
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// Construct a basic_datagram_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a datagram socket without opening it. The open()
|
||||
* function must be called before data can be sent or received on the socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
*/
|
||||
explicit basic_datagram_socket(asio::io_service& io_service)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_datagram_socket.
|
||||
/**
|
||||
* This constructor creates and opens a datagram socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_datagram_socket, opening it and binding it to the given
|
||||
/// local endpoint.
|
||||
/**
|
||||
* This constructor creates a datagram socket and automatically opens it bound
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the datagram
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_datagram_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a datagram socket object to hold an existing
|
||||
* native socket.
|
||||
*
|
||||
* @param io_service The io_service object that the datagram socket will use
|
||||
* to dispatch handlers for any asynchronous operations performed on the
|
||||
* socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_datagram_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol, const native_type& native_socket)
|
||||
: basic_socket<Protocol, DatagramSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
* call will block until the data has been sent successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One ore more data buffers to be sent on the socket.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The send operation can only be used with a connected socket. Use
|
||||
* the send_to function to send data on an unconnected datagram socket.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code socket.send(asio::buffer(data, size)); @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send some data on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
* call will block until the data has been sent successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One ore more data buffers to be sent on the socket.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The send operation can only be used with a connected socket. Use
|
||||
* the send_to function to send data on an unconnected datagram socket.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send(
|
||||
this->implementation, buffers, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send some data on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
* call will block until the data has been sent successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @note The send operation can only be used with a connected socket. Use
|
||||
* the send_to function to send data on an unconnected datagram socket.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return this->service.send(this->implementation, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
* call will block until the data has been sent successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket. Although
|
||||
* the buffers object may be copied as necessary, ownership of the underlying
|
||||
* memory blocks is retained by the caller, which must guarantee that they
|
||||
* remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected datagram
|
||||
* socket.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.async_send(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
|
||||
{
|
||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send on a connected socket.
|
||||
/**
|
||||
* This function is used to send data on the datagram socket. The function
|
||||
* call will block until the data has been sent successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket. Although
|
||||
* the buffers object may be copied as necessary, ownership of the underlying
|
||||
* memory blocks is retained by the caller, which must guarantee that they
|
||||
* remain valid until the handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The async_send operation can only be used with a connected socket.
|
||||
* Use the async_send_to function to send data on an unconnected datagram
|
||||
* socket.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, WriteHandler handler)
|
||||
{
|
||||
this->service.async_send(this->implementation, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
/**
|
||||
* This function is used to send a datagram to the specified remote endpoint.
|
||||
* The function call will block until the data has been sent successfully or
|
||||
* an error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent to the remote endpoint.
|
||||
*
|
||||
* @param destination The remote endpoint to which the data will be sent.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* asio::ip::udp::endpoint destination(
|
||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||
* socket.send_to(asio::buffer(data, size), destination);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send_to(
|
||||
this->implementation, buffers, destination, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
/**
|
||||
* This function is used to send a datagram to the specified remote endpoint.
|
||||
* The function call will block until the data has been sent successfully or
|
||||
* an error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent to the remote endpoint.
|
||||
*
|
||||
* @param destination The remote endpoint to which the data will be sent.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination, socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send_to(
|
||||
this->implementation, buffers, destination, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
/**
|
||||
* This function is used to send a datagram to the specified remote endpoint.
|
||||
* The function call will block until the data has been sent successfully or
|
||||
* an error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent to the remote endpoint.
|
||||
*
|
||||
* @param destination The remote endpoint to which the data will be sent.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send_to(const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.send_to(this->implementation,
|
||||
buffers, destination, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
/**
|
||||
* This function is used to asynchronously send a datagram to the specified
|
||||
* remote endpoint. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent to the remote endpoint.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param destination The remote endpoint to which the data will be sent.
|
||||
* Copies will be made of the endpoint as required.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* asio::ip::udp::endpoint destination(
|
||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||
* socket.async_send_to(
|
||||
* asio::buffer(data, size), destination, handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send_to(const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination, WriteHandler handler)
|
||||
{
|
||||
this->service.async_send_to(this->implementation, buffers, destination, 0,
|
||||
handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
/**
|
||||
* This function is used to asynchronously send a datagram to the specified
|
||||
* remote endpoint. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent to the remote endpoint.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param destination The remote endpoint to which the data will be sent.
|
||||
* Copies will be made of the endpoint as required.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send_to(const ConstBufferSequence& buffers,
|
||||
const endpoint_type& destination, socket_base::message_flags flags,
|
||||
WriteHandler handler)
|
||||
{
|
||||
this->service.async_send_to(this->implementation, buffers, destination,
|
||||
flags, handler);
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
/**
|
||||
* This function is used to receive data on the datagram socket. The function
|
||||
* call will block until data has been received successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The receive operation can only be used with a connected socket. Use
|
||||
* the receive_from function to receive data on an unconnected datagram
|
||||
* socket.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code socket.receive(asio::buffer(data, size)); @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive(
|
||||
this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
/**
|
||||
* This function is used to receive data on the datagram socket. The function
|
||||
* call will block until data has been received successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The receive operation can only be used with a connected socket. Use
|
||||
* the receive_from function to receive data on an unconnected datagram
|
||||
* socket.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive(
|
||||
this->implementation, buffers, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
/**
|
||||
* This function is used to receive data on the datagram socket. The function
|
||||
* call will block until data has been received successfully or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @note The receive operation can only be used with a connected socket. Use
|
||||
* the receive_from function to receive data on an unconnected datagram
|
||||
* socket.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return this->service.receive(this->implementation, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
/**
|
||||
* This function is used to asynchronously receive data from the datagram
|
||||
* socket. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
* datagram socket.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* socket.async_receive(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive on a connected socket.
|
||||
/**
|
||||
* This function is used to asynchronously receive data from the datagram
|
||||
* socket. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The async_receive operation can only be used with a connected socket.
|
||||
* Use the async_receive_from function to receive data on an unconnected
|
||||
* datagram socket.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive(this->implementation, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
/**
|
||||
* This function is used to receive a datagram. The function call will block
|
||||
* until data has been received successfully or an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param sender_endpoint An endpoint object that receives the endpoint of
|
||||
* the remote sender of the datagram.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* asio::ip::udp::endpoint sender_endpoint;
|
||||
* socket.receive_from(
|
||||
* asio::buffer(data, size), sender_endpoint);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||
endpoint_type& sender_endpoint)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive_from(
|
||||
this->implementation, buffers, sender_endpoint, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
/**
|
||||
* This function is used to receive a datagram. The function call will block
|
||||
* until data has been received successfully or an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param sender_endpoint An endpoint object that receives the endpoint of
|
||||
* the remote sender of the datagram.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive_from(
|
||||
this->implementation, buffers, sender_endpoint, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
/**
|
||||
* This function is used to receive a datagram. The function call will block
|
||||
* until data has been received successfully or an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param sender_endpoint An endpoint object that receives the endpoint of
|
||||
* the remote sender of the datagram.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive_from(const MutableBufferSequence& buffers,
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.receive_from(this->implementation, buffers,
|
||||
sender_endpoint, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
/**
|
||||
* This function is used to asynchronously receive a datagram. The function
|
||||
* call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param sender_endpoint An endpoint object that receives the endpoint of
|
||||
* the remote sender of the datagram. Ownership of the sender_endpoint object
|
||||
* is retained by the caller, which must guarantee that it is valid until the
|
||||
* handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::system_error& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code socket.async_receive_from(
|
||||
* asio::buffer(data, size), 0, sender_endpoint, handler); @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive_from(const MutableBufferSequence& buffers,
|
||||
endpoint_type& sender_endpoint, ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive_from(this->implementation, buffers,
|
||||
sender_endpoint, 0, handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
/**
|
||||
* This function is used to asynchronously receive a datagram. The function
|
||||
* call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param sender_endpoint An endpoint object that receives the endpoint of
|
||||
* the remote sender of the datagram. Ownership of the sender_endpoint object
|
||||
* is retained by the caller, which must guarantee that it is valid until the
|
||||
* handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive_from(const MutableBufferSequence& buffers,
|
||||
endpoint_type& sender_endpoint, socket_base::message_flags flags,
|
||||
ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive_from(this->implementation, buffers,
|
||||
sender_endpoint, flags, handler);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP
|
381
libtorrent/include/asio/basic_deadline_timer.hpp
Normal file
|
@ -0,0 +1,381 @@
|
|||
//
|
||||
// basic_deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_DEADLINE_TIMER_HPP
|
||||
#define ASIO_BASIC_DEADLINE_TIMER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_io_object.hpp"
|
||||
#include "asio/deadline_timer_service.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Provides waitable timer functionality.
|
||||
/**
|
||||
* The basic_deadline_timer class template provides the ability to perform a
|
||||
* blocking or asynchronous wait for a timer to expire.
|
||||
*
|
||||
* Most applications will use the asio::deadline_timer typedef.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Examples
|
||||
* Performing a blocking wait:
|
||||
* @code
|
||||
* // Construct a timer without setting an expiry time.
|
||||
* asio::deadline_timer timer(io_service);
|
||||
*
|
||||
* // Set an expiry time relative to now.
|
||||
* timer.expires_from_now(boost::posix_time::seconds(5));
|
||||
*
|
||||
* // Wait for the timer to expire.
|
||||
* timer.wait();
|
||||
* @endcode
|
||||
*
|
||||
* @par
|
||||
* Performing an asynchronous wait:
|
||||
* @code
|
||||
* void handler(const asio::error_code& error)
|
||||
* {
|
||||
* if (!error)
|
||||
* {
|
||||
* // Timer expired.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // Construct a timer with an absolute expiry time.
|
||||
* asio::deadline_timer timer(io_service,
|
||||
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
|
||||
*
|
||||
* // Start an asynchronous wait.
|
||||
* timer.async_wait(handler);
|
||||
* @endcode
|
||||
*
|
||||
* @par Changing an active deadline_timer's expiry time
|
||||
*
|
||||
* Changing the expiry time of a timer while there are pending asynchronous
|
||||
* waits causes those wait operations to be cancelled. To ensure that the action
|
||||
* associated with the timer is performed only once, use something like this:
|
||||
* used:
|
||||
*
|
||||
* @code
|
||||
* void on_some_event()
|
||||
* {
|
||||
* if (my_timer.expires_from_now(seconds(5)) > 0)
|
||||
* {
|
||||
* // We managed to cancel the timer. Start new asynchronous wait.
|
||||
* my_timer.async_wait(on_timeout);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Too late, timer has already expired!
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* void on_timeout(const asio::error_code& e)
|
||||
* {
|
||||
* if (e != asio::error::operation_aborted)
|
||||
* {
|
||||
* // Timer was not cancelled, take necessary action.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @li The asio::basic_deadline_timer::expires_from_now() function
|
||||
* cancels any pending asynchronous waits, and returns the number of
|
||||
* asynchronous waits that were cancelled. If it returns 0 then you were too
|
||||
* late and the wait handler has already been executed, or will soon be
|
||||
* executed. If it returns 1 then the wait handler was successfully cancelled.
|
||||
*
|
||||
* @li If a wait handler is cancelled, the asio::error_code passed to
|
||||
* it contains the value asio::error::operation_aborted.
|
||||
*/
|
||||
template <typename Time,
|
||||
typename TimeTraits = asio::time_traits<Time>,
|
||||
typename TimerService = deadline_timer_service<Time, TimeTraits> >
|
||||
class basic_deadline_timer
|
||||
: public basic_io_object<TimerService>
|
||||
{
|
||||
public:
|
||||
/// The time traits type.
|
||||
typedef TimeTraits traits_type;
|
||||
|
||||
/// The time type.
|
||||
typedef typename traits_type::time_type time_type;
|
||||
|
||||
/// The duration type.
|
||||
typedef typename traits_type::duration_type duration_type;
|
||||
|
||||
/// Constructor.
|
||||
/**
|
||||
* This constructor creates a timer without setting an expiry time. The
|
||||
* expires_at() or expires_from_now() functions must be called to set an
|
||||
* expiry time before the timer can be waited on.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*/
|
||||
explicit basic_deadline_timer(asio::io_service& io_service)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time as an absolute time.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, expressed
|
||||
* as an absolute time.
|
||||
*/
|
||||
basic_deadline_timer(asio::io_service& io_service,
|
||||
const time_type& expiry_time)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Constructor to set a particular expiry time relative to now.
|
||||
/**
|
||||
* This constructor creates a timer and sets the expiry time.
|
||||
*
|
||||
* @param io_service The io_service object that the timer will use to dispatch
|
||||
* handlers for any asynchronous operations performed on the timer.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer, relative to
|
||||
* now.
|
||||
*/
|
||||
basic_deadline_timer(asio::io_service& io_service,
|
||||
const duration_type& expiry_time)
|
||||
: basic_io_object<TimerService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.expires_from_now(this->implementation, expiry_time, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
* operations against the timer. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
std::size_t cancel()
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.cancel(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous operations that are waiting on the timer.
|
||||
/**
|
||||
* This function forces the completion of any pending asynchronous wait
|
||||
* operations against the timer. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* Cancelling the timer does not change the expiry time.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*/
|
||||
std::size_t cancel(asio::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
time_type expires_at() const
|
||||
{
|
||||
return this->service.expires_at(this->implementation);
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
std::size_t expires_at(const time_type& expiry_time)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.expires_at(
|
||||
this->implementation, expiry_time, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time as an absolute time.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*/
|
||||
std::size_t expires_at(const time_type& expiry_time,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.expires_at(this->implementation, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Get the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function may be used to obtain the timer's current expiry time.
|
||||
* Whether the timer has expired or not does not affect this value.
|
||||
*/
|
||||
duration_type expires_from_now() const
|
||||
{
|
||||
return this->service.expires_from_now(this->implementation);
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
std::size_t expires_from_now(const duration_type& expiry_time)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Set the timer's expiry time relative to now.
|
||||
/**
|
||||
* This function sets the expiry time. Any pending asynchronous wait
|
||||
* operations will be cancelled. The handler for each cancelled operation will
|
||||
* be invoked with the asio::error::operation_aborted error code.
|
||||
*
|
||||
* @param expiry_time The expiry time to be used for the timer.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of asynchronous operations that were cancelled.
|
||||
*/
|
||||
std::size_t expires_from_now(const duration_type& expiry_time,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.expires_from_now(
|
||||
this->implementation, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
/**
|
||||
* This function is used to wait for the timer to expire. This function
|
||||
* blocks and does not return until the timer has expired.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void wait()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.wait(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Perform a blocking wait on the timer.
|
||||
/**
|
||||
* This function is used to wait for the timer to expire. This function
|
||||
* blocks and does not return until the timer has expired.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
void wait(asio::error_code& ec)
|
||||
{
|
||||
this->service.wait(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous wait on the timer.
|
||||
/**
|
||||
* This function may be used to initiate an asynchronous wait against the
|
||||
* timer. It always returns immediately.
|
||||
*
|
||||
* For each call to async_wait(), the supplied handler will be called exactly
|
||||
* once. The handler will be called when:
|
||||
*
|
||||
* @li The timer has expired.
|
||||
*
|
||||
* @li The timer was cancelled, in which case the handler is passed the error
|
||||
* code asio::error::operation_aborted.
|
||||
*
|
||||
* @param handler The handler to be called when the timer expires. Copies
|
||||
* will be made of the handler as required. The function signature of the
|
||||
* handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*/
|
||||
template <typename WaitHandler>
|
||||
void async_wait(WaitHandler handler)
|
||||
{
|
||||
this->service.async_wait(this->implementation, handler);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_DEADLINE_TIMER_HPP
|
75
libtorrent/include/asio/basic_io_object.hpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// basic_io_object.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_IO_OBJECT_HPP
|
||||
#define ASIO_BASIC_IO_OBJECT_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Base class for all I/O objects.
|
||||
template <typename IoObjectService>
|
||||
class basic_io_object
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The type of the service that will be used to provide I/O operations.
|
||||
typedef IoObjectService service_type;
|
||||
|
||||
/// The underlying implementation type of I/O object.
|
||||
typedef typename service_type::implementation_type implementation_type;
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
/**
|
||||
* This function may be used to obtain the io_service object that the I/O
|
||||
* object uses to dispatch handlers for asynchronous operations.
|
||||
*
|
||||
* @return A reference to the io_service object that the I/O object will use
|
||||
* to dispatch handlers. Ownership is not transferred to the caller.
|
||||
*/
|
||||
asio::io_service& io_service()
|
||||
{
|
||||
return service.io_service();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Construct a basic_io_object.
|
||||
explicit basic_io_object(asio::io_service& io_service)
|
||||
: service(asio::use_service<IoObjectService>(io_service))
|
||||
{
|
||||
service.construct(implementation);
|
||||
}
|
||||
|
||||
/// Protected destructor to prevent deletion through this type.
|
||||
~basic_io_object()
|
||||
{
|
||||
service.destroy(implementation);
|
||||
}
|
||||
|
||||
// The backend service implementation.
|
||||
service_type& service;
|
||||
|
||||
// The underlying native implementation.
|
||||
implementation_type implementation;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_IO_OBJECT_HPP
|
972
libtorrent/include/asio/basic_socket.hpp
Normal file
|
@ -0,0 +1,972 @@
|
|||
//
|
||||
// basic_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_SOCKET_HPP
|
||||
#define ASIO_BASIC_SOCKET_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/basic_io_object.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/socket_base.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Provides socket functionality.
|
||||
/**
|
||||
* The basic_socket class template provides functionality that is common to both
|
||||
* stream-oriented and datagram-oriented sockets.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*/
|
||||
template <typename Protocol, typename SocketService>
|
||||
class basic_socket
|
||||
: public basic_io_object<SocketService>,
|
||||
public socket_base
|
||||
{
|
||||
public:
|
||||
/// The native representation of a socket.
|
||||
typedef typename SocketService::native_type native_type;
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// A basic_socket is always the lowest layer.
|
||||
typedef basic_socket<Protocol, SocketService> lowest_layer_type;
|
||||
|
||||
/// Construct a basic_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a socket without opening it.
|
||||
*
|
||||
* @param io_service The io_service object that the socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_socket(asio::io_service& io_service)
|
||||
: basic_io_object<SocketService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_socket.
|
||||
/**
|
||||
* This constructor creates and opens a socket.
|
||||
*
|
||||
* @param io_service The io_service object that the socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_io_object<SocketService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, protocol, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Construct a basic_socket, opening it and binding it to the given local
|
||||
/// endpoint.
|
||||
/**
|
||||
* This constructor creates a socket and automatically opens it bound to the
|
||||
* specified endpoint on the local machine. The protocol used is the protocol
|
||||
* associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the socket will
|
||||
* be bound.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_socket(asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_io_object<SocketService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, endpoint.protocol(), ec);
|
||||
asio::detail::throw_error(ec);
|
||||
this->service.bind(this->implementation, endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Construct a basic_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a socket object to hold an existing native socket.
|
||||
*
|
||||
* @param io_service The io_service object that the socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket A native socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol, const native_type& native_socket)
|
||||
: basic_io_object<SocketService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, protocol, native_socket, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
/**
|
||||
* This function returns a reference to the lowest layer in a stack of
|
||||
* layers. Since a basic_socket cannot contain any further layers, it simply
|
||||
* returns a reference to itself.
|
||||
*
|
||||
* @return A reference to the lowest layer in the stack of layers. Ownership
|
||||
* is not transferred to the caller.
|
||||
*/
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Open the socket using the specified protocol.
|
||||
/**
|
||||
* This function opens the socket so that it will use the specified protocol.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* socket.open(asio::ip::tcp::v4());
|
||||
* @endcode
|
||||
*/
|
||||
void open(const protocol_type& protocol = protocol_type())
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, protocol, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Open the socket using the specified protocol.
|
||||
/**
|
||||
* This function opens the socket so that it will use the specified protocol.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::error_code ec;
|
||||
* socket.open(asio::ip::tcp::v4(), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code open(const protocol_type& protocol,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.open(this->implementation, protocol, ec);
|
||||
}
|
||||
|
||||
/// Assign an existing native socket to the socket.
|
||||
/*
|
||||
* This function opens the socket to hold an existing native socket.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param native_socket A native socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void assign(const protocol_type& protocol, const native_type& native_socket)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, protocol, native_socket, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Assign an existing native socket to the socket.
|
||||
/*
|
||||
* This function opens the socket to hold an existing native socket.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param native_socket A native socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code assign(const protocol_type& protocol,
|
||||
const native_type& native_socket, asio::error_code& ec)
|
||||
{
|
||||
return this->service.assign(this->implementation,
|
||||
protocol, native_socket, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is open.
|
||||
bool is_open() const
|
||||
{
|
||||
return this->service.is_open(this->implementation);
|
||||
}
|
||||
|
||||
/// Close the socket.
|
||||
/**
|
||||
* This function is used to close the socket. Any asynchronous send, receive
|
||||
* or connect operations will be cancelled immediately, and will complete
|
||||
* with the asio::error::operation_aborted error.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.close(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Close the socket.
|
||||
/**
|
||||
* This function is used to close the socket. Any asynchronous send, receive
|
||||
* or connect operations will be cancelled immediately, and will complete
|
||||
* with the asio::error::operation_aborted error.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* socket.close(ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return this->service.close(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Get the native socket representation.
|
||||
/**
|
||||
* This function may be used to obtain the underlying representation of the
|
||||
* socket. This is intended to allow access to native socket functionality
|
||||
* that is not otherwise provided.
|
||||
*/
|
||||
native_type native()
|
||||
{
|
||||
return this->service.native(this->implementation);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the socket.
|
||||
/**
|
||||
* This function causes all outstanding asynchronous connect, send and receive
|
||||
* operations to finish immediately, and the handlers for cancelled operations
|
||||
* will be passed the asio::error::operation_aborted error.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void cancel()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.cancel(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the socket.
|
||||
/**
|
||||
* This function causes all outstanding asynchronous connect, send and receive
|
||||
* operations to finish immediately, and the handlers for cancelled operations
|
||||
* will be passed the asio::error::operation_aborted error.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code cancel(asio::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is at the out-of-band data mark.
|
||||
/**
|
||||
* This function is used to check whether the socket input is currently
|
||||
* positioned at the out-of-band data mark.
|
||||
*
|
||||
* @return A bool indicating whether the socket is at the out-of-band data
|
||||
* mark.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
bool at_mark() const
|
||||
{
|
||||
asio::error_code ec;
|
||||
bool b = this->service.at_mark(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return b;
|
||||
}
|
||||
|
||||
/// Determine whether the socket is at the out-of-band data mark.
|
||||
/**
|
||||
* This function is used to check whether the socket input is currently
|
||||
* positioned at the out-of-band data mark.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return A bool indicating whether the socket is at the out-of-band data
|
||||
* mark.
|
||||
*/
|
||||
bool at_mark(asio::error_code& ec) const
|
||||
{
|
||||
return this->service.at_mark(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Determine the number of bytes available for reading.
|
||||
/**
|
||||
* This function is used to determine the number of bytes that may be read
|
||||
* without blocking.
|
||||
*
|
||||
* @return The number of bytes that may be read without blocking, or 0 if an
|
||||
* error occurs.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
std::size_t available() const
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.available(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Determine the number of bytes available for reading.
|
||||
/**
|
||||
* This function is used to determine the number of bytes that may be read
|
||||
* without blocking.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @return The number of bytes that may be read without blocking, or 0 if an
|
||||
* error occurs.
|
||||
*/
|
||||
std::size_t available(asio::error_code& ec) const
|
||||
{
|
||||
return this->service.available(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Bind the socket to the given local endpoint.
|
||||
/**
|
||||
* This function binds the socket to the specified endpoint on the local
|
||||
* machine.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the socket will
|
||||
* be bound.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* socket.open(asio::ip::tcp::v4());
|
||||
* socket.bind(asio::ip::tcp::endpoint(
|
||||
* asio::ip::tcp::v4(), 12345));
|
||||
* @endcode
|
||||
*/
|
||||
void bind(const endpoint_type& endpoint)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.bind(this->implementation, endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Bind the socket to the given local endpoint.
|
||||
/**
|
||||
* This function binds the socket to the specified endpoint on the local
|
||||
* machine.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the socket will
|
||||
* be bound.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* socket.open(asio::ip::tcp::v4());
|
||||
* asio::error_code ec;
|
||||
* socket.bind(asio::ip::tcp::endpoint(
|
||||
* asio::ip::tcp::v4(), 12345), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code bind(const endpoint_type& endpoint,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.bind(this->implementation, endpoint, ec);
|
||||
}
|
||||
|
||||
/// Connect the socket to the specified endpoint.
|
||||
/**
|
||||
* This function is used to connect a socket to the specified remote endpoint.
|
||||
* The function call will block until the connection is successfully made or
|
||||
* an error occurs.
|
||||
*
|
||||
* The socket is automatically opened if it is not already open. If the
|
||||
* connect fails, and the socket was automatically opened, the socket is
|
||||
* returned to the closed state.
|
||||
*
|
||||
* @param peer_endpoint The remote endpoint to which the socket will be
|
||||
* connected.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint(
|
||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||
* socket.connect(endpoint);
|
||||
* @endcode
|
||||
*/
|
||||
void connect(const endpoint_type& peer_endpoint)
|
||||
{
|
||||
asio::error_code ec;
|
||||
if (!is_open())
|
||||
{
|
||||
this->service.open(this->implementation, peer_endpoint.protocol(), ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
this->service.connect(this->implementation, peer_endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Connect the socket to the specified endpoint.
|
||||
/**
|
||||
* This function is used to connect a socket to the specified remote endpoint.
|
||||
* The function call will block until the connection is successfully made or
|
||||
* an error occurs.
|
||||
*
|
||||
* The socket is automatically opened if it is not already open. If the
|
||||
* connect fails, and the socket was automatically opened, the socket is
|
||||
* returned to the closed state.
|
||||
*
|
||||
* @param peer_endpoint The remote endpoint to which the socket will be
|
||||
* connected.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint(
|
||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||
* asio::error_code ec;
|
||||
* socket.connect(endpoint, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code connect(const endpoint_type& peer_endpoint,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
if (!is_open())
|
||||
{
|
||||
if (this->service.open(this->implementation,
|
||||
peer_endpoint.protocol(), ec))
|
||||
{
|
||||
return ec;
|
||||
}
|
||||
}
|
||||
|
||||
return this->service.connect(this->implementation, peer_endpoint, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous connect.
|
||||
/**
|
||||
* This function is used to asynchronously connect a socket to the specified
|
||||
* remote endpoint. The function call always returns immediately.
|
||||
*
|
||||
* The socket is automatically opened if it is not already open. If the
|
||||
* connect fails, and the socket was automatically opened, the socket is
|
||||
* returned to the closed state.
|
||||
*
|
||||
* @param peer_endpoint The remote endpoint to which the socket will be
|
||||
* connected. Copies will be made of the endpoint object as required.
|
||||
*
|
||||
* @param handler The handler to be called when the connection operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* void connect_handler(const asio::error_code& error)
|
||||
* {
|
||||
* if (!error)
|
||||
* {
|
||||
* // Connect succeeded.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint(
|
||||
* asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||
* socket.async_connect(endpoint, connect_handler);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename ConnectHandler>
|
||||
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
|
||||
{
|
||||
if (!is_open())
|
||||
{
|
||||
asio::error_code ec;
|
||||
if (this->service.open(this->implementation,
|
||||
peer_endpoint.protocol(), ec))
|
||||
{
|
||||
this->io_service().post(asio::detail::bind_handler(handler, ec));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->service.async_connect(this->implementation, peer_endpoint, handler);
|
||||
}
|
||||
|
||||
/// Set an option on the socket.
|
||||
/**
|
||||
* This function is used to set an option on the socket.
|
||||
*
|
||||
* @param option The new option value to be set on the socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @sa SettableSocketOption @n
|
||||
* asio::socket_base::broadcast @n
|
||||
* asio::socket_base::do_not_route @n
|
||||
* asio::socket_base::keep_alive @n
|
||||
* asio::socket_base::linger @n
|
||||
* asio::socket_base::receive_buffer_size @n
|
||||
* asio::socket_base::receive_low_watermark @n
|
||||
* asio::socket_base::reuse_address @n
|
||||
* asio::socket_base::send_buffer_size @n
|
||||
* asio::socket_base::send_low_watermark @n
|
||||
* asio::ip::multicast::join_group @n
|
||||
* asio::ip::multicast::leave_group @n
|
||||
* asio::ip::multicast::enable_loopback @n
|
||||
* asio::ip::multicast::outbound_interface @n
|
||||
* asio::ip::multicast::hops @n
|
||||
* asio::ip::tcp::no_delay
|
||||
*
|
||||
* @par Example
|
||||
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::no_delay option(true);
|
||||
* socket.set_option(option);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SettableSocketOption>
|
||||
void set_option(const SettableSocketOption& option)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.set_option(this->implementation, option, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Set an option on the socket.
|
||||
/**
|
||||
* This function is used to set an option on the socket.
|
||||
*
|
||||
* @param option The new option value to be set on the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @sa SettableSocketOption @n
|
||||
* asio::socket_base::broadcast @n
|
||||
* asio::socket_base::do_not_route @n
|
||||
* asio::socket_base::keep_alive @n
|
||||
* asio::socket_base::linger @n
|
||||
* asio::socket_base::receive_buffer_size @n
|
||||
* asio::socket_base::receive_low_watermark @n
|
||||
* asio::socket_base::reuse_address @n
|
||||
* asio::socket_base::send_buffer_size @n
|
||||
* asio::socket_base::send_low_watermark @n
|
||||
* asio::ip::multicast::join_group @n
|
||||
* asio::ip::multicast::leave_group @n
|
||||
* asio::ip::multicast::enable_loopback @n
|
||||
* asio::ip::multicast::outbound_interface @n
|
||||
* asio::ip::multicast::hops @n
|
||||
* asio::ip::tcp::no_delay
|
||||
*
|
||||
* @par Example
|
||||
* Setting the IPPROTO_TCP/TCP_NODELAY option:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::no_delay option(true);
|
||||
* asio::error_code ec;
|
||||
* socket.set_option(option, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SettableSocketOption>
|
||||
asio::error_code set_option(const SettableSocketOption& option,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.set_option(this->implementation, option, ec);
|
||||
}
|
||||
|
||||
/// Get an option from the socket.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the socket.
|
||||
*
|
||||
* @param option The option value to be obtained from the socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @sa GettableSocketOption @n
|
||||
* asio::socket_base::broadcast @n
|
||||
* asio::socket_base::do_not_route @n
|
||||
* asio::socket_base::keep_alive @n
|
||||
* asio::socket_base::linger @n
|
||||
* asio::socket_base::receive_buffer_size @n
|
||||
* asio::socket_base::receive_low_watermark @n
|
||||
* asio::socket_base::reuse_address @n
|
||||
* asio::socket_base::send_buffer_size @n
|
||||
* asio::socket_base::send_low_watermark @n
|
||||
* asio::ip::multicast::join_group @n
|
||||
* asio::ip::multicast::leave_group @n
|
||||
* asio::ip::multicast::enable_loopback @n
|
||||
* asio::ip::multicast::outbound_interface @n
|
||||
* asio::ip::multicast::hops @n
|
||||
* asio::ip::tcp::no_delay
|
||||
*
|
||||
* @par Example
|
||||
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket::keep_alive option;
|
||||
* socket.get_option(option);
|
||||
* bool is_set = option.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename GettableSocketOption>
|
||||
void get_option(GettableSocketOption& option) const
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.get_option(this->implementation, option, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Get an option from the socket.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the socket.
|
||||
*
|
||||
* @param option The option value to be obtained from the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @sa GettableSocketOption @n
|
||||
* asio::socket_base::broadcast @n
|
||||
* asio::socket_base::do_not_route @n
|
||||
* asio::socket_base::keep_alive @n
|
||||
* asio::socket_base::linger @n
|
||||
* asio::socket_base::receive_buffer_size @n
|
||||
* asio::socket_base::receive_low_watermark @n
|
||||
* asio::socket_base::reuse_address @n
|
||||
* asio::socket_base::send_buffer_size @n
|
||||
* asio::socket_base::send_low_watermark @n
|
||||
* asio::ip::multicast::join_group @n
|
||||
* asio::ip::multicast::leave_group @n
|
||||
* asio::ip::multicast::enable_loopback @n
|
||||
* asio::ip::multicast::outbound_interface @n
|
||||
* asio::ip::multicast::hops @n
|
||||
* asio::ip::tcp::no_delay
|
||||
*
|
||||
* @par Example
|
||||
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket::keep_alive option;
|
||||
* asio::error_code ec;
|
||||
* socket.get_option(option, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* bool is_set = option.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename GettableSocketOption>
|
||||
asio::error_code get_option(GettableSocketOption& option,
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
return this->service.get_option(this->implementation, option, ec);
|
||||
}
|
||||
|
||||
/// Perform an IO control command on the socket.
|
||||
/**
|
||||
* This function is used to execute an IO control command on the socket.
|
||||
*
|
||||
* @param command The IO control command to be performed on the socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @sa IoControlCommand @n
|
||||
* asio::socket_base::bytes_readable @n
|
||||
* asio::socket_base::non_blocking_io
|
||||
*
|
||||
* @par Example
|
||||
* Getting the number of bytes ready to read:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket::bytes_readable command;
|
||||
* socket.io_control(command);
|
||||
* std::size_t bytes_readable = command.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename IoControlCommand>
|
||||
void io_control(IoControlCommand& command)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.io_control(this->implementation, command, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Perform an IO control command on the socket.
|
||||
/**
|
||||
* This function is used to execute an IO control command on the socket.
|
||||
*
|
||||
* @param command The IO control command to be performed on the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @sa IoControlCommand @n
|
||||
* asio::socket_base::bytes_readable @n
|
||||
* asio::socket_base::non_blocking_io
|
||||
*
|
||||
* @par Example
|
||||
* Getting the number of bytes ready to read:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket::bytes_readable command;
|
||||
* asio::error_code ec;
|
||||
* socket.io_control(command, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* std::size_t bytes_readable = command.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename IoControlCommand>
|
||||
asio::error_code io_control(IoControlCommand& command,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.io_control(this->implementation, command, ec);
|
||||
}
|
||||
|
||||
/// Get the local endpoint of the socket.
|
||||
/**
|
||||
* This function is used to obtain the locally bound endpoint of the socket.
|
||||
*
|
||||
* @returns An object that represents the local endpoint of the socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type local_endpoint() const
|
||||
{
|
||||
asio::error_code ec;
|
||||
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return ep;
|
||||
}
|
||||
|
||||
/// Get the local endpoint of the socket.
|
||||
/**
|
||||
* This function is used to obtain the locally bound endpoint of the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns An object that represents the local endpoint of the socket.
|
||||
* Returns a default-constructed endpoint object if an error occurred.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type local_endpoint(asio::error_code& ec) const
|
||||
{
|
||||
return this->service.local_endpoint(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Get the remote endpoint of the socket.
|
||||
/**
|
||||
* This function is used to obtain the remote endpoint of the socket.
|
||||
*
|
||||
* @returns An object that represents the remote endpoint of the socket.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type remote_endpoint() const
|
||||
{
|
||||
asio::error_code ec;
|
||||
endpoint_type ep = this->service.remote_endpoint(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return ep;
|
||||
}
|
||||
|
||||
/// Get the remote endpoint of the socket.
|
||||
/**
|
||||
* This function is used to obtain the remote endpoint of the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns An object that represents the remote endpoint of the socket.
|
||||
* Returns a default-constructed endpoint object if an error occurred.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type remote_endpoint(asio::error_code& ec) const
|
||||
{
|
||||
return this->service.remote_endpoint(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Disable sends or receives on the socket.
|
||||
/**
|
||||
* This function is used to disable send operations, receive operations, or
|
||||
* both.
|
||||
*
|
||||
* @param what Determines what types of operation will no longer be allowed.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* Shutting down the send side of the socket:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* socket.shutdown(asio::ip::tcp::socket::shutdown_send);
|
||||
* @endcode
|
||||
*/
|
||||
void shutdown(shutdown_type what)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.shutdown(this->implementation, what, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Disable sends or receives on the socket.
|
||||
/**
|
||||
* This function is used to disable send operations, receive operations, or
|
||||
* both.
|
||||
*
|
||||
* @param what Determines what types of operation will no longer be allowed.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* Shutting down the send side of the socket:
|
||||
* @code
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code shutdown(shutdown_type what,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.shutdown(this->implementation, what, ec);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Protected destructor to prevent deletion through this type.
|
||||
~basic_socket()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_SOCKET_HPP
|
824
libtorrent/include/asio/basic_socket_acceptor.hpp
Normal file
|
@ -0,0 +1,824 @@
|
|||
//
|
||||
// basic_socket_acceptor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP
|
||||
#define ASIO_BASIC_SOCKET_ACCEPTOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/basic_io_object.hpp"
|
||||
#include "asio/basic_socket.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/socket_acceptor_service.hpp"
|
||||
#include "asio/socket_base.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Provides the ability to accept new connections.
|
||||
/**
|
||||
* The basic_socket_acceptor class template is used for accepting new socket
|
||||
* connections.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Example
|
||||
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
|
||||
* acceptor.open(endpoint.protocol());
|
||||
* acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
|
||||
* acceptor.bind(endpoint);
|
||||
* acceptor.listen();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename SocketAcceptorService = socket_acceptor_service<Protocol> >
|
||||
class basic_socket_acceptor
|
||||
: public basic_io_object<SocketAcceptorService>,
|
||||
public socket_base
|
||||
{
|
||||
public:
|
||||
/// The native representation of an acceptor.
|
||||
typedef typename SocketAcceptorService::native_type native_type;
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// Construct an acceptor without opening it.
|
||||
/**
|
||||
* This constructor creates an acceptor without opening it to listen for new
|
||||
* connections. The open() function must be called before the acceptor can
|
||||
* accept new socket connections.
|
||||
*
|
||||
* @param io_service The io_service object that the acceptor will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* acceptor.
|
||||
*/
|
||||
explicit basic_socket_acceptor(asio::io_service& io_service)
|
||||
: basic_io_object<SocketAcceptorService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct an open acceptor.
|
||||
/**
|
||||
* This constructor creates an acceptor and automatically opens it.
|
||||
*
|
||||
* @param io_service The io_service object that the acceptor will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* acceptor.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_socket_acceptor(asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_io_object<SocketAcceptorService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, protocol, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Construct an acceptor opened on the given endpoint.
|
||||
/**
|
||||
* This constructor creates an acceptor and automatically opens it to listen
|
||||
* for new connections on the specified endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the acceptor will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* acceptor.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine on which the acceptor
|
||||
* will listen for new connections.
|
||||
*
|
||||
* @param reuse_addr Whether the constructor should set the socket option
|
||||
* socket_base::reuse_address.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note This constructor is equivalent to the following code:
|
||||
* @code
|
||||
* basic_socket_acceptor<Protocol> acceptor(io_service);
|
||||
* acceptor.open(endpoint.protocol());
|
||||
* if (reuse_addr)
|
||||
* acceptor.set_option(socket_base::reuse_address(true));
|
||||
* acceptor.bind(endpoint);
|
||||
* acceptor.listen(listen_backlog);
|
||||
* @endcode
|
||||
*/
|
||||
basic_socket_acceptor(asio::io_service& io_service,
|
||||
const endpoint_type& endpoint, bool reuse_addr = true)
|
||||
: basic_io_object<SocketAcceptorService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, endpoint.protocol(), ec);
|
||||
asio::detail::throw_error(ec);
|
||||
if (reuse_addr)
|
||||
{
|
||||
this->service.set_option(this->implementation,
|
||||
socket_base::reuse_address(true), ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
this->service.bind(this->implementation, endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
this->service.listen(this->implementation,
|
||||
socket_base::max_connections, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Construct a basic_socket_acceptor on an existing native acceptor.
|
||||
/**
|
||||
* This constructor creates an acceptor object to hold an existing native
|
||||
* acceptor.
|
||||
*
|
||||
* @param io_service The io_service object that the acceptor will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the
|
||||
* acceptor.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_acceptor A native acceptor.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_socket_acceptor(asio::io_service& io_service,
|
||||
const protocol_type& protocol, const native_type& native_acceptor)
|
||||
: basic_io_object<SocketAcceptorService>(io_service)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, protocol, native_acceptor, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Open the acceptor using the specified protocol.
|
||||
/**
|
||||
* This function opens the socket acceptor so that it will use the specified
|
||||
* protocol.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* acceptor.open(asio::ip::tcp::v4());
|
||||
* @endcode
|
||||
*/
|
||||
void open(const protocol_type& protocol = protocol_type())
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.open(this->implementation, protocol, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Open the acceptor using the specified protocol.
|
||||
/**
|
||||
* This function opens the socket acceptor so that it will use the specified
|
||||
* protocol.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* asio::error_code ec;
|
||||
* acceptor.open(asio::ip::tcp::v4(), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code open(const protocol_type& protocol,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.open(this->implementation, protocol, ec);
|
||||
}
|
||||
|
||||
/// Assigns an existing native acceptor to the acceptor.
|
||||
/*
|
||||
* This function opens the acceptor to hold an existing native acceptor.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param native_acceptor A native acceptor.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void assign(const protocol_type& protocol, const native_type& native_acceptor)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.assign(this->implementation, protocol, native_acceptor, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Assigns an existing native acceptor to the acceptor.
|
||||
/*
|
||||
* This function opens the acceptor to hold an existing native acceptor.
|
||||
*
|
||||
* @param protocol An object specifying which protocol is to be used.
|
||||
*
|
||||
* @param native_acceptor A native acceptor.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code assign(const protocol_type& protocol,
|
||||
const native_type& native_acceptor, asio::error_code& ec)
|
||||
{
|
||||
return this->service.assign(this->implementation,
|
||||
protocol, native_acceptor, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the acceptor is open.
|
||||
bool is_open() const
|
||||
{
|
||||
return this->service.is_open(this->implementation);
|
||||
}
|
||||
|
||||
/// Bind the acceptor to the given local endpoint.
|
||||
/**
|
||||
* This function binds the socket acceptor to the specified endpoint on the
|
||||
* local machine.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the socket
|
||||
* acceptor will be bound.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* acceptor.open(asio::ip::tcp::v4());
|
||||
* acceptor.bind(asio::ip::tcp::endpoint(12345));
|
||||
* @endcode
|
||||
*/
|
||||
void bind(const endpoint_type& endpoint)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.bind(this->implementation, endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Bind the acceptor to the given local endpoint.
|
||||
/**
|
||||
* This function binds the socket acceptor to the specified endpoint on the
|
||||
* local machine.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the socket
|
||||
* acceptor will be bound.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* acceptor.open(asio::ip::tcp::v4());
|
||||
* asio::error_code ec;
|
||||
* acceptor.bind(asio::ip::tcp::endpoint(12345), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code bind(const endpoint_type& endpoint,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.bind(this->implementation, endpoint, ec);
|
||||
}
|
||||
|
||||
/// Place the acceptor into the state where it will listen for new
|
||||
/// connections.
|
||||
/**
|
||||
* This function puts the socket acceptor into the state where it may accept
|
||||
* new connections.
|
||||
*
|
||||
* @param backlog The maximum length of the queue of pending connections.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void listen(int backlog = socket_base::max_connections)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.listen(this->implementation, backlog, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Place the acceptor into the state where it will listen for new
|
||||
/// connections.
|
||||
/**
|
||||
* This function puts the socket acceptor into the state where it may accept
|
||||
* new connections.
|
||||
*
|
||||
* @param backlog The maximum length of the queue of pending connections.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* acceptor.listen(asio::socket_base::max_connections, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code listen(int backlog, asio::error_code& ec)
|
||||
{
|
||||
return this->service.listen(this->implementation, backlog, ec);
|
||||
}
|
||||
|
||||
/// Close the acceptor.
|
||||
/**
|
||||
* This function is used to close the acceptor. Any asynchronous accept
|
||||
* operations will be cancelled immediately.
|
||||
*
|
||||
* A subsequent call to open() is required before the acceptor can again be
|
||||
* used to again perform socket accept operations.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.close(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Close the acceptor.
|
||||
/**
|
||||
* This function is used to close the acceptor. Any asynchronous accept
|
||||
* operations will be cancelled immediately.
|
||||
*
|
||||
* A subsequent call to open() is required before the acceptor can again be
|
||||
* used to again perform socket accept operations.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* acceptor.close(ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return this->service.close(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Get the native acceptor representation.
|
||||
/**
|
||||
* This function may be used to obtain the underlying representation of the
|
||||
* acceptor. This is intended to allow access to native acceptor functionality
|
||||
* that is not otherwise provided.
|
||||
*/
|
||||
native_type native()
|
||||
{
|
||||
return this->service.native(this->implementation);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the acceptor.
|
||||
/**
|
||||
* This function causes all outstanding asynchronous connect, send and receive
|
||||
* operations to finish immediately, and the handlers for cancelled operations
|
||||
* will be passed the asio::error::operation_aborted error.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
void cancel()
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.cancel(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the acceptor.
|
||||
/**
|
||||
* This function causes all outstanding asynchronous connect, send and receive
|
||||
* operations to finish immediately, and the handlers for cancelled operations
|
||||
* will be passed the asio::error::operation_aborted error.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
asio::error_code cancel(asio::error_code& ec)
|
||||
{
|
||||
return this->service.cancel(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Set an option on the acceptor.
|
||||
/**
|
||||
* This function is used to set an option on the acceptor.
|
||||
*
|
||||
* @param option The new option value to be set on the acceptor.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @sa SettableSocketOption @n
|
||||
* asio::socket_base::reuse_address
|
||||
* asio::socket_base::enable_connection_aborted
|
||||
*
|
||||
* @par Example
|
||||
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::acceptor::reuse_address option(true);
|
||||
* acceptor.set_option(option);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SettableSocketOption>
|
||||
void set_option(const SettableSocketOption& option)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.set_option(this->implementation, option, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Set an option on the acceptor.
|
||||
/**
|
||||
* This function is used to set an option on the acceptor.
|
||||
*
|
||||
* @param option The new option value to be set on the acceptor.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @sa SettableSocketOption @n
|
||||
* asio::socket_base::reuse_address
|
||||
* asio::socket_base::enable_connection_aborted
|
||||
*
|
||||
* @par Example
|
||||
* Setting the SOL_SOCKET/SO_REUSEADDR option:
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::acceptor::reuse_address option(true);
|
||||
* asio::error_code ec;
|
||||
* acceptor.set_option(option, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SettableSocketOption>
|
||||
asio::error_code set_option(const SettableSocketOption& option,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.set_option(this->implementation, option, ec);
|
||||
}
|
||||
|
||||
/// Get an option from the acceptor.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the
|
||||
* acceptor.
|
||||
*
|
||||
* @param option The option value to be obtained from the acceptor.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @sa GettableSocketOption @n
|
||||
* asio::socket_base::reuse_address
|
||||
*
|
||||
* @par Example
|
||||
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::acceptor::reuse_address option;
|
||||
* acceptor.get_option(option);
|
||||
* bool is_set = option.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename GettableSocketOption>
|
||||
void get_option(GettableSocketOption& option)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.get_option(this->implementation, option, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Get an option from the acceptor.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the
|
||||
* acceptor.
|
||||
*
|
||||
* @param option The option value to be obtained from the acceptor.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @sa GettableSocketOption @n
|
||||
* asio::socket_base::reuse_address
|
||||
*
|
||||
* @par Example
|
||||
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::acceptor::reuse_address option;
|
||||
* asio::error_code ec;
|
||||
* acceptor.get_option(option, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* bool is_set = option.get();
|
||||
* @endcode
|
||||
*/
|
||||
template <typename GettableSocketOption>
|
||||
asio::error_code get_option(GettableSocketOption& option,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.get_option(this->implementation, option, ec);
|
||||
}
|
||||
|
||||
/// Get the local endpoint of the acceptor.
|
||||
/**
|
||||
* This function is used to obtain the locally bound endpoint of the acceptor.
|
||||
*
|
||||
* @returns An object that represents the local endpoint of the acceptor.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type local_endpoint() const
|
||||
{
|
||||
asio::error_code ec;
|
||||
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return ep;
|
||||
}
|
||||
|
||||
/// Get the local endpoint of the acceptor.
|
||||
/**
|
||||
* This function is used to obtain the locally bound endpoint of the acceptor.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns An object that represents the local endpoint of the acceptor.
|
||||
* Returns a default-constructed endpoint object if an error occurred and the
|
||||
* error handler did not throw an exception.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::error_code ec;
|
||||
* asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
endpoint_type local_endpoint(asio::error_code& ec) const
|
||||
{
|
||||
return this->service.local_endpoint(this->implementation, ec);
|
||||
}
|
||||
|
||||
/// Accept a new connection.
|
||||
/**
|
||||
* This function is used to accept a new connection from a peer into the
|
||||
* given socket. The function call will block until a new connection has been
|
||||
* accepted successfully or an error occurs.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* acceptor.accept(socket);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SocketService>
|
||||
void accept(basic_socket<protocol_type, SocketService>& peer)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.accept(this->implementation, peer, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Accept a new connection.
|
||||
/**
|
||||
* This function is used to accept a new connection from a peer into the
|
||||
* given socket. The function call will block until a new connection has been
|
||||
* accepted successfully or an error occurs.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::soocket socket(io_service);
|
||||
* asio::error_code ec;
|
||||
* acceptor.accept(socket, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SocketService>
|
||||
asio::error_code accept(
|
||||
basic_socket<protocol_type, SocketService>& peer,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.accept(this->implementation, peer, 0, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous accept.
|
||||
/**
|
||||
* This function is used to asynchronously accept a new connection into a
|
||||
* socket. The function call always returns immediately.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
* Ownership of the peer object is retained by the caller, which must
|
||||
* guarantee that it is valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the accept operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* void accept_handler(const asio::error_code& error)
|
||||
* {
|
||||
* if (!error)
|
||||
* {
|
||||
* // Accept succeeded.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* acceptor.async_accept(socket, accept_handler);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SocketService, typename AcceptHandler>
|
||||
void async_accept(basic_socket<protocol_type, SocketService>& peer,
|
||||
AcceptHandler handler)
|
||||
{
|
||||
this->service.async_accept(this->implementation, peer, 0, handler);
|
||||
}
|
||||
|
||||
/// Accept a new connection and obtain the endpoint of the peer
|
||||
/**
|
||||
* This function is used to accept a new connection from a peer into the
|
||||
* given socket, and additionally provide the endpoint of the remote peer.
|
||||
* The function call will block until a new connection has been accepted
|
||||
* successfully or an error occurs.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
*
|
||||
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
||||
* the remote peer.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint;
|
||||
* acceptor.accept(socket, endpoint);
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SocketService>
|
||||
void accept(basic_socket<protocol_type, SocketService>& peer,
|
||||
endpoint_type& peer_endpoint)
|
||||
{
|
||||
asio::error_code ec;
|
||||
this->service.accept(this->implementation, peer, &peer_endpoint, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
}
|
||||
|
||||
/// Accept a new connection and obtain the endpoint of the peer
|
||||
/**
|
||||
* This function is used to accept a new connection from a peer into the
|
||||
* given socket, and additionally provide the endpoint of the remote peer.
|
||||
* The function call will block until a new connection has been accepted
|
||||
* successfully or an error occurs.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
*
|
||||
* @param peer_endpoint An endpoint object which will receive the endpoint of
|
||||
* the remote peer.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @par Example
|
||||
* @code
|
||||
* asio::ip::tcp::acceptor acceptor(io_service);
|
||||
* ...
|
||||
* asio::ip::tcp::socket socket(io_service);
|
||||
* asio::ip::tcp::endpoint endpoint;
|
||||
* asio::error_code ec;
|
||||
* acceptor.accept(socket, endpoint, ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template <typename SocketService>
|
||||
asio::error_code accept(
|
||||
basic_socket<protocol_type, SocketService>& peer,
|
||||
endpoint_type& peer_endpoint, asio::error_code& ec)
|
||||
{
|
||||
return this->service.accept(this->implementation, peer, &peer_endpoint, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous accept.
|
||||
/**
|
||||
* This function is used to asynchronously accept a new connection into a
|
||||
* socket, and additionally obtain the endpoint of the remote peer. The
|
||||
* function call always returns immediately.
|
||||
*
|
||||
* @param peer The socket into which the new connection will be accepted.
|
||||
* Ownership of the peer object is retained by the caller, which must
|
||||
* guarantee that it is valid until the handler is called.
|
||||
*
|
||||
* @param peer_endpoint An endpoint object into which the endpoint of the
|
||||
* remote peer will be written. Ownership of the peer_endpoint object is
|
||||
* retained by the caller, which must guarantee that it is valid until the
|
||||
* handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the accept operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*/
|
||||
template <typename SocketService, typename AcceptHandler>
|
||||
void async_accept(basic_socket<protocol_type, SocketService>& peer,
|
||||
endpoint_type& peer_endpoint, AcceptHandler handler)
|
||||
{
|
||||
this->service.async_accept(this->implementation,
|
||||
peer, &peer_endpoint, handler);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
|
146
libtorrent/include/asio/basic_socket_iostream.hpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// basic_socket_iostream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_SOCKET_IOSTREAM_HPP
|
||||
#define ASIO_BASIC_SOCKET_IOSTREAM_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_socket_streambuf.hpp"
|
||||
#include "asio/stream_socket_service.hpp"
|
||||
|
||||
#if !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY)
|
||||
#define ASIO_SOCKET_IOSTREAM_MAX_ARITY 5
|
||||
#endif // !defined(ASIO_SOCKET_IOSTREAM_MAX_ARITY)
|
||||
|
||||
// A macro that should expand to:
|
||||
// template <typename T1, ..., typename Tn>
|
||||
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
|
||||
// : basic_iostream<char>(&this->boost::base_from_member<
|
||||
// basic_socket_streambuf<Protocol, StreamSocketService> >::member)
|
||||
// {
|
||||
// if (rdbuf()->connect(x1, ..., xn) == 0)
|
||||
// this->setstate(std::ios_base::failbit);
|
||||
// }
|
||||
// This macro should only persist within this file.
|
||||
|
||||
#define ASIO_PRIVATE_CTR_DEF(z, n, data) \
|
||||
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||
explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||
: std::basic_iostream<char>(&this->boost::base_from_member< \
|
||||
basic_socket_streambuf<Protocol, StreamSocketService> >::member) \
|
||||
{ \
|
||||
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
|
||||
this->setstate(std::ios_base::failbit); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
// A macro that should expand to:
|
||||
// template <typename T1, ..., typename Tn>
|
||||
// void connect(T1 x1, ..., Tn xn)
|
||||
// {
|
||||
// if (rdbuf()->connect(x1, ..., xn) == 0)
|
||||
// this->setstate(std::ios_base::failbit);
|
||||
// }
|
||||
// This macro should only persist within this file.
|
||||
|
||||
#define ASIO_PRIVATE_CONNECT_DEF(z, n, data) \
|
||||
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||
void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||
{ \
|
||||
if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
|
||||
this->setstate(std::ios_base::failbit); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Iostream interface for a socket.
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||
class basic_socket_iostream
|
||||
: public boost::base_from_member<
|
||||
basic_socket_streambuf<Protocol, StreamSocketService> >,
|
||||
public std::basic_iostream<char>
|
||||
{
|
||||
public:
|
||||
/// Construct a basic_socket_iostream without establishing a connection.
|
||||
basic_socket_iostream()
|
||||
: std::basic_iostream<char>(&this->boost::base_from_member<
|
||||
basic_socket_streambuf<Protocol, StreamSocketService> >::member)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Establish a connection to an endpoint corresponding to a resolver query.
|
||||
/**
|
||||
* This constructor automatically establishes a connection based on the
|
||||
* supplied resolver query parameters. The arguments are used to construct
|
||||
* a resolver query object.
|
||||
*/
|
||||
template <typename T1, ..., typename TN>
|
||||
explicit basic_socket_iostream(T1 t1, ..., TN tn);
|
||||
#else
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
1, BOOST_PP_INC(ASIO_SOCKET_IOSTREAM_MAX_ARITY),
|
||||
ASIO_PRIVATE_CTR_DEF, _ )
|
||||
#endif
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Establish a connection to an endpoint corresponding to a resolver query.
|
||||
/**
|
||||
* This function automatically establishes a connection based on the supplied
|
||||
* resolver query parameters. The arguments are used to construct a resolver
|
||||
* query object.
|
||||
*/
|
||||
template <typename T1, ..., typename TN>
|
||||
void connect(T1 t1, ..., TN tn);
|
||||
#else
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
1, BOOST_PP_INC(ASIO_SOCKET_IOSTREAM_MAX_ARITY),
|
||||
ASIO_PRIVATE_CONNECT_DEF, _ )
|
||||
#endif
|
||||
|
||||
/// Close the connection.
|
||||
void close()
|
||||
{
|
||||
if (rdbuf()->close() == 0)
|
||||
this->setstate(std::ios_base::failbit);
|
||||
}
|
||||
|
||||
/// Return a pointer to the underlying streambuf.
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* rdbuf() const
|
||||
{
|
||||
return const_cast<basic_socket_streambuf<Protocol, StreamSocketService>*>(
|
||||
&this->boost::base_from_member<
|
||||
basic_socket_streambuf<Protocol, StreamSocketService> >::member);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#undef ASIO_PRIVATE_CTR_DEF
|
||||
#undef ASIO_PRIVATE_CONNECT_DEF
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_SOCKET_IOSTREAM_HPP
|
284
libtorrent/include/asio/basic_socket_streambuf.hpp
Normal file
|
@ -0,0 +1,284 @@
|
|||
//
|
||||
// basic_socket_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_SOCKET_STREAMBUF_HPP
|
||||
#define ASIO_BASIC_SOCKET_STREAMBUF_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <streambuf>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_socket.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/stream_socket_service.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
#if !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
||||
#define ASIO_SOCKET_STREAMBUF_MAX_ARITY 5
|
||||
#endif // !defined(ASIO_SOCKET_STREAMBUF_MAX_ARITY)
|
||||
|
||||
// A macro that should expand to:
|
||||
// template <typename T1, ..., typename Tn>
|
||||
// basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||
// T1 x1, ..., Tn xn)
|
||||
// {
|
||||
// init_buffers();
|
||||
// asio::error_code ec;
|
||||
// this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||
// typedef typename Protocol::resolver_query resolver_query;
|
||||
// resolver_query query(x1, ..., xn);
|
||||
// resolve_and_connect(query, ec);
|
||||
// return !ec ? this : 0;
|
||||
// }
|
||||
// This macro should only persist within this file.
|
||||
|
||||
#define ASIO_PRIVATE_CONNECT_DEF( z, n, data ) \
|
||||
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* connect( \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
|
||||
{ \
|
||||
init_buffers(); \
|
||||
asio::error_code ec; \
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec); \
|
||||
typedef typename Protocol::resolver_query resolver_query; \
|
||||
resolver_query query(BOOST_PP_ENUM_PARAMS(n, x)); \
|
||||
resolve_and_connect(query, ec); \
|
||||
return !ec ? this : 0; \
|
||||
} \
|
||||
/**/
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Iostream streambuf for a socket.
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||
class basic_socket_streambuf
|
||||
: public std::streambuf,
|
||||
private boost::base_from_member<io_service>,
|
||||
public basic_socket<Protocol, StreamSocketService>
|
||||
{
|
||||
public:
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// Construct a basic_socket_streambuf without establishing a connection.
|
||||
basic_socket_streambuf()
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
boost::base_from_member<asio::io_service>::member),
|
||||
unbuffered_(false)
|
||||
{
|
||||
init_buffers();
|
||||
}
|
||||
|
||||
/// Destructor flushes buffered data.
|
||||
virtual ~basic_socket_streambuf()
|
||||
{
|
||||
if (pptr() != pbase())
|
||||
overflow(traits_type::eof());
|
||||
}
|
||||
|
||||
/// Establish a connection.
|
||||
/**
|
||||
* This function establishes a connection to the specified endpoint.
|
||||
*
|
||||
* @return \c this if a connection was successfully established, a null
|
||||
* pointer otherwise.
|
||||
*/
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||
const endpoint_type& endpoint)
|
||||
{
|
||||
init_buffers();
|
||||
asio::error_code ec;
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||
this->basic_socket<Protocol, StreamSocketService>::connect(endpoint, ec);
|
||||
return !ec ? this : 0;
|
||||
}
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Establish a connection.
|
||||
/**
|
||||
* This function automatically establishes a connection based on the supplied
|
||||
* resolver query parameters. The arguments are used to construct a resolver
|
||||
* query object.
|
||||
*
|
||||
* @return \c this if a connection was successfully established, a null
|
||||
* pointer otherwise.
|
||||
*/
|
||||
template <typename T1, ..., typename TN>
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* connect(
|
||||
T1 t1, ..., TN tn);
|
||||
#else
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
1, BOOST_PP_INC(ASIO_SOCKET_STREAMBUF_MAX_ARITY),
|
||||
ASIO_PRIVATE_CONNECT_DEF, _ )
|
||||
#endif
|
||||
|
||||
/// Close the connection.
|
||||
/**
|
||||
* @return \c this if a connection was successfully established, a null
|
||||
* pointer otherwise.
|
||||
*/
|
||||
basic_socket_streambuf<Protocol, StreamSocketService>* close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
sync();
|
||||
this->basic_socket<Protocol, StreamSocketService>::close(ec);
|
||||
if (!ec)
|
||||
init_buffers();
|
||||
return !ec ? this : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
int_type underflow()
|
||||
{
|
||||
if (gptr() == egptr())
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t bytes_transferred = this->service.receive(
|
||||
this->implementation,
|
||||
asio::buffer(asio::buffer(get_buffer_) + putback_max),
|
||||
0, ec);
|
||||
if (ec)
|
||||
return traits_type::eof();
|
||||
setg(get_buffer_.begin(), get_buffer_.begin() + putback_max,
|
||||
get_buffer_.begin() + putback_max + bytes_transferred);
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
}
|
||||
|
||||
int_type overflow(int_type c)
|
||||
{
|
||||
if (unbuffered_)
|
||||
{
|
||||
if (traits_type::eq_int_type(c, traits_type::eof()))
|
||||
{
|
||||
// Nothing to do.
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send the single character immediately.
|
||||
asio::error_code ec;
|
||||
char_type ch = traits_type::to_char_type(c);
|
||||
this->service.send(this->implementation,
|
||||
asio::buffer(&ch, sizeof(char_type)), 0, ec);
|
||||
if (ec)
|
||||
return traits_type::eof();
|
||||
return c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send all data in the output buffer.
|
||||
asio::const_buffer buffer =
|
||||
asio::buffer(pbase(), pptr() - pbase());
|
||||
while (asio::buffer_size(buffer) > 0)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t bytes_transferred = this->service.send(
|
||||
this->implementation, asio::buffer(buffer),
|
||||
0, ec);
|
||||
if (ec)
|
||||
return traits_type::eof();
|
||||
buffer = buffer + bytes_transferred;
|
||||
}
|
||||
setp(put_buffer_.begin(), put_buffer_.end());
|
||||
|
||||
// If the new character is eof then our work here is done.
|
||||
if (traits_type::eq_int_type(c, traits_type::eof()))
|
||||
return traits_type::not_eof(c);
|
||||
|
||||
// Add the new character to the output buffer.
|
||||
*pptr() = traits_type::to_char_type(c);
|
||||
pbump(1);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int sync()
|
||||
{
|
||||
return overflow(traits_type::eof());
|
||||
}
|
||||
|
||||
std::streambuf* setbuf(char_type* s, std::streamsize n)
|
||||
{
|
||||
if (pptr() == pbase() && s == 0 && n == 0)
|
||||
{
|
||||
unbuffered_ = true;
|
||||
setp(0, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void init_buffers()
|
||||
{
|
||||
setg(get_buffer_.begin(),
|
||||
get_buffer_.begin() + putback_max,
|
||||
get_buffer_.begin() + putback_max);
|
||||
if (unbuffered_)
|
||||
setp(0, 0);
|
||||
else
|
||||
setp(put_buffer_.begin(), put_buffer_.end());
|
||||
}
|
||||
|
||||
void resolve_and_connect(const typename Protocol::resolver_query& query,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
typedef typename Protocol::resolver resolver_type;
|
||||
typedef typename Protocol::resolver_iterator iterator_type;
|
||||
resolver_type resolver(
|
||||
boost::base_from_member<asio::io_service>::member);
|
||||
iterator_type i = resolver.resolve(query, ec);
|
||||
if (!ec)
|
||||
{
|
||||
iterator_type end;
|
||||
ec = asio::error::host_not_found;
|
||||
while (ec && i != end)
|
||||
{
|
||||
this->basic_socket<Protocol, StreamSocketService>::close();
|
||||
this->basic_socket<Protocol, StreamSocketService>::connect(*i, ec);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum { putback_max = 8 };
|
||||
enum { buffer_size = 512 };
|
||||
boost::array<char, buffer_size> get_buffer_;
|
||||
boost::array<char, buffer_size> put_buffer_;
|
||||
bool unbuffered_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#undef ASIO_PRIVATE_CONNECT_DEF
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP
|
718
libtorrent/include/asio/basic_stream_socket.hpp
Normal file
|
@ -0,0 +1,718 @@
|
|||
//
|
||||
// basic_stream_socket.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_STREAM_SOCKET_HPP
|
||||
#define ASIO_BASIC_STREAM_SOCKET_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_socket.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/stream_socket_service.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Provides stream-oriented socket functionality.
|
||||
/**
|
||||
* The basic_stream_socket class template provides asynchronous and blocking
|
||||
* stream-oriented socket functionality.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Protocol,
|
||||
typename StreamSocketService = stream_socket_service<Protocol> >
|
||||
class basic_stream_socket
|
||||
: public basic_socket<Protocol, StreamSocketService>
|
||||
{
|
||||
public:
|
||||
/// The native representation of a socket.
|
||||
typedef typename StreamSocketService::native_type native_type;
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
/// Construct a basic_stream_socket without opening it.
|
||||
/**
|
||||
* This constructor creates a stream socket without opening it. The socket
|
||||
* needs to be opened and then connected or accepted before data can be sent
|
||||
* or received on it.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*/
|
||||
explicit basic_stream_socket(asio::io_service& io_service)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct and open a basic_stream_socket.
|
||||
/**
|
||||
* This constructor creates and opens a stream socket. The socket needs to be
|
||||
* connected or accepted before data can be sent or received on it.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service, protocol)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_stream_socket, opening it and binding it to the given
|
||||
/// local endpoint.
|
||||
/**
|
||||
* This constructor creates a stream socket and automatically opens it bound
|
||||
* to the specified endpoint on the local machine. The protocol used is the
|
||||
* protocol associated with the given endpoint.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param endpoint An endpoint on the local machine to which the stream
|
||||
* socket will be bound.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(asio::io_service& io_service,
|
||||
const endpoint_type& endpoint)
|
||||
: basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a basic_stream_socket on an existing native socket.
|
||||
/**
|
||||
* This constructor creates a stream socket object to hold an existing native
|
||||
* socket.
|
||||
*
|
||||
* @param io_service The io_service object that the stream socket will use to
|
||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||
*
|
||||
* @param protocol An object specifying protocol parameters to be used.
|
||||
*
|
||||
* @param native_socket The new underlying socket implementation.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*/
|
||||
basic_stream_socket(asio::io_service& io_service,
|
||||
const protocol_type& protocol, const native_type& native_socket)
|
||||
: basic_socket<Protocol, StreamSocketService>(
|
||||
io_service, protocol, native_socket)
|
||||
{
|
||||
}
|
||||
|
||||
/// Send some data on the socket.
|
||||
/**
|
||||
* This function is used to send data on the stream socket. The function
|
||||
* call will block until one or more bytes of the data has been sent
|
||||
* successfully, or an until error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref write function if you need to ensure that all data
|
||||
* is written before the blocking operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.send(asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send(
|
||||
this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send some data on the socket.
|
||||
/**
|
||||
* This function is used to send data on the stream socket. The function
|
||||
* call will block until one or more bytes of the data has been sent
|
||||
* successfully, or an until error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @returns The number of bytes sent.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref write function if you need to ensure that all data
|
||||
* is written before the blocking operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.send(asio::buffer(data, size), 0);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send(
|
||||
this->implementation, buffers, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Send some data on the socket.
|
||||
/**
|
||||
* This function is used to send data on the stream socket. The function
|
||||
* call will block until one or more bytes of the data has been sent
|
||||
* successfully, or an until error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes sent. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref write function if you need to ensure that all data
|
||||
* is written before the blocking operation completes.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return this->service.send(this->implementation, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
/**
|
||||
* This function is used to asynchronously send data on the stream socket.
|
||||
* The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket. Although
|
||||
* the buffers object may be copied as necessary, ownership of the underlying
|
||||
* memory blocks is retained by the caller, which must guarantee that they
|
||||
* remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
* data is written before the asynchronous operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.async_send(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
|
||||
{
|
||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
/**
|
||||
* This function is used to asynchronously send data on the stream socket.
|
||||
* The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more data buffers to be sent on the socket. Although
|
||||
* the buffers object may be copied as necessary, ownership of the underlying
|
||||
* memory blocks is retained by the caller, which must guarantee that they
|
||||
* remain valid until the handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the send call is to be made.
|
||||
*
|
||||
* @param handler The handler to be called when the send operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes sent.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The send operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
* data is written before the asynchronous operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To send a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.async_send(asio::buffer(data, size), 0, handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on sending multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send(const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, WriteHandler handler)
|
||||
{
|
||||
this->service.async_send(this->implementation, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Receive some data on the socket.
|
||||
/**
|
||||
* This function is used to receive data on the stream socket. The function
|
||||
* call will block until one or more bytes of data has been received
|
||||
* successfully, or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure. An error code of
|
||||
* asio::error::eof indicates that the connection was closed by the
|
||||
* peer.
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||
* requested amount of data is read before the blocking operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* socket.receive(asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive some data on the socket.
|
||||
/**
|
||||
* This function is used to receive data on the stream socket. The function
|
||||
* call will block until one or more bytes of data has been received
|
||||
* successfully, or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @returns The number of bytes received.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure. An error code of
|
||||
* asio::error::eof indicates that the connection was closed by the
|
||||
* peer.
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||
* requested amount of data is read before the blocking operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* socket.receive(asio::buffer(data, size), 0);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive(
|
||||
this->implementation, buffers, flags, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Receive some data on a connected socket.
|
||||
/**
|
||||
* This function is used to receive data on the stream socket. The function
|
||||
* call will block until one or more bytes of data has been received
|
||||
* successfully, or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes received. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that the
|
||||
* requested amount of data is read before the blocking operation completes.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return this->service.receive(this->implementation, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
/**
|
||||
* This function is used to asynchronously receive data from the stream
|
||||
* socket. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref async_read function if you need to ensure
|
||||
* that the requested amount of data is received before the asynchronous
|
||||
* operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* socket.async_receive(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
/**
|
||||
* This function is used to asynchronously receive data from the stream
|
||||
* socket. The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be received.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param flags Flags specifying how the receive call is to be made.
|
||||
*
|
||||
* @param handler The handler to be called when the receive operation
|
||||
* completes. Copies will be made of the handler as required. The function
|
||||
* signature of the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes received.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The receive operation may not receive all of the requested number of
|
||||
* bytes. Consider using the @ref async_read function if you need to ensure
|
||||
* that the requested amount of data is received before the asynchronous
|
||||
* operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To receive into a single data buffer use the @ref buffer function as
|
||||
* follows:
|
||||
* @code
|
||||
* socket.async_receive(asio::buffer(data, size), 0, handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on receiving into
|
||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive(const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive(this->implementation, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Write some data to the socket.
|
||||
/**
|
||||
* This function is used to write data to the stream socket. The function call
|
||||
* will block until one or more bytes of the data has been written
|
||||
* successfully, or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be written to the socket.
|
||||
*
|
||||
* @returns The number of bytes written.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure. An error code of
|
||||
* asio::error::eof indicates that the connection was closed by the
|
||||
* peer.
|
||||
*
|
||||
* @note The write_some operation may not transmit all of the data to the
|
||||
* peer. Consider using the @ref write function if you need to ensure that
|
||||
* all data is written before the blocking operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To write a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.write_some(asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on writing multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Write some data to the socket.
|
||||
/**
|
||||
* This function is used to write data to the stream socket. The function call
|
||||
* will block until one or more bytes of the data has been written
|
||||
* successfully, or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more data buffers to be written to the socket.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The write_some operation may not transmit all of the data to the
|
||||
* peer. Consider using the @ref write function if you need to ensure that
|
||||
* all data is written before the blocking operation completes.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.send(this->implementation, buffers, 0, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write.
|
||||
/**
|
||||
* This function is used to asynchronously write data to the stream socket.
|
||||
* The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more data buffers to be written to the socket.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the write operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The write operation may not transmit all of the data to the peer.
|
||||
* Consider using the @ref async_write function if you need to ensure that all
|
||||
* data is written before the asynchronous operation completes.
|
||||
*
|
||||
* @par Example
|
||||
* To write a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.async_write_some(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on writing multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence& buffers,
|
||||
WriteHandler handler)
|
||||
{
|
||||
this->service.async_send(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
|
||||
/// Read some data from the socket.
|
||||
/**
|
||||
* This function is used to read data from the stream socket. The function
|
||||
* call will block until one or more bytes of data has been read successfully,
|
||||
* or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be read.
|
||||
*
|
||||
* @returns The number of bytes read.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure. An error code of
|
||||
* asio::error::eof indicates that the connection was closed by the
|
||||
* peer.
|
||||
*
|
||||
* @note The read_some operation may not read all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that
|
||||
* the requested amount of data is read before the blocking operation
|
||||
* completes.
|
||||
*
|
||||
* @par Example
|
||||
* To read into a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.read_some(asio::buffer(data, size));
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on reading into multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
asio::error_code ec;
|
||||
std::size_t s = this->service.receive(this->implementation, buffers, 0, ec);
|
||||
asio::detail::throw_error(ec);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Read some data from the socket.
|
||||
/**
|
||||
* This function is used to read data from the stream socket. The function
|
||||
* call will block until one or more bytes of data has been read successfully,
|
||||
* or until an error occurs.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be read.
|
||||
*
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*
|
||||
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||
*
|
||||
* @note The read_some operation may not read all of the requested number of
|
||||
* bytes. Consider using the @ref read function if you need to ensure that
|
||||
* the requested amount of data is read before the blocking operation
|
||||
* completes.
|
||||
*/
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return this->service.receive(this->implementation, buffers, 0, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read.
|
||||
/**
|
||||
* This function is used to asynchronously read data from the stream socket.
|
||||
* The function call always returns immediately.
|
||||
*
|
||||
* @param buffers One or more buffers into which the data will be read.
|
||||
* Although the buffers object may be copied as necessary, ownership of the
|
||||
* underlying memory blocks is retained by the caller, which must guarantee
|
||||
* that they remain valid until the handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the read operation completes.
|
||||
* Copies will be made of the handler as required. The function signature of
|
||||
* the handler must be:
|
||||
* @code void handler(
|
||||
* const asio::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the handler will not be invoked from within this function. Invocation
|
||||
* of the handler will be performed in a manner equivalent to using
|
||||
* asio::io_service::post().
|
||||
*
|
||||
* @note The read operation may not read all of the requested number of bytes.
|
||||
* Consider using the @ref async_read function if you need to ensure that the
|
||||
* requested amount of data is read before the asynchronous operation
|
||||
* completes.
|
||||
*
|
||||
* @par Example
|
||||
* To read into a single data buffer use the @ref buffer function as follows:
|
||||
* @code
|
||||
* socket.async_read_some(asio::buffer(data, size), handler);
|
||||
* @endcode
|
||||
* See the @ref buffer documentation for information on reading into multiple
|
||||
* buffers in one go, and how to use it with arrays, boost::array or
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence& buffers,
|
||||
ReadHandler handler)
|
||||
{
|
||||
this->service.async_receive(this->implementation, buffers, 0, handler);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_STREAM_SOCKET_HPP
|
200
libtorrent/include/asio/basic_streambuf.hpp
Normal file
|
@ -0,0 +1,200 @@
|
|||
//
|
||||
// basic_streambuf.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BASIC_STREAMBUF_HPP
|
||||
#define ASIO_BASIC_STREAMBUF_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <streambuf>
|
||||
#include <vector>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffer.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Automatically resizable buffer class based on std::streambuf.
|
||||
template <typename Allocator = std::allocator<char> >
|
||||
class basic_streambuf
|
||||
: public std::streambuf,
|
||||
private noncopyable
|
||||
{
|
||||
public:
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The type used to represent the get area as a list of buffers.
|
||||
typedef implementation_defined const_buffers_type;
|
||||
|
||||
/// The type used to represent the put area as a list of buffers.
|
||||
typedef implementation_defined mutable_buffers_type;
|
||||
#else
|
||||
typedef asio::const_buffers_1 const_buffers_type;
|
||||
typedef asio::mutable_buffers_1 mutable_buffers_type;
|
||||
#endif
|
||||
|
||||
/// Construct a buffer with a specified maximum size.
|
||||
explicit basic_streambuf(
|
||||
std::size_t max_size = (std::numeric_limits<std::size_t>::max)(),
|
||||
const Allocator& allocator = Allocator())
|
||||
: max_size_(max_size),
|
||||
buffer_(allocator)
|
||||
{
|
||||
std::size_t pend = (std::min<std::size_t>)(max_size_, buffer_delta);
|
||||
buffer_.resize((std::max<std::size_t>)(pend, 1));
|
||||
setg(&buffer_[0], &buffer_[0], &buffer_[0]);
|
||||
setp(&buffer_[0], &buffer_[0] + pend);
|
||||
}
|
||||
|
||||
/// Return the size of the get area in characters.
|
||||
std::size_t size() const
|
||||
{
|
||||
return pptr() - gptr();
|
||||
}
|
||||
|
||||
/// Return the maximum size of the buffer.
|
||||
std::size_t max_size() const
|
||||
{
|
||||
return max_size_;
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the get area.
|
||||
const_buffers_type data() const
|
||||
{
|
||||
return asio::buffer(asio::const_buffer(gptr(),
|
||||
(pptr() - gptr()) * sizeof(char_type)));
|
||||
}
|
||||
|
||||
/// Get a list of buffers that represents the put area, with the given size.
|
||||
mutable_buffers_type prepare(std::size_t size)
|
||||
{
|
||||
reserve(size);
|
||||
return asio::buffer(asio::mutable_buffer(
|
||||
pptr(), size * sizeof(char_type)));
|
||||
}
|
||||
|
||||
/// Move the start of the put area by the specified number of characters.
|
||||
void commit(std::size_t n)
|
||||
{
|
||||
if (pptr() + n > epptr())
|
||||
n = epptr() - pptr();
|
||||
pbump(static_cast<int>(n));
|
||||
}
|
||||
|
||||
/// Move the start of the get area by the specified number of characters.
|
||||
void consume(std::size_t n)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
sbumpc();
|
||||
--n;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
enum { buffer_delta = 128 };
|
||||
|
||||
int_type underflow()
|
||||
{
|
||||
if (gptr() < pptr())
|
||||
{
|
||||
setg(&buffer_[0], gptr(), pptr());
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
}
|
||||
|
||||
int_type overflow(int_type c)
|
||||
{
|
||||
if (!traits_type::eq_int_type(c, traits_type::eof()))
|
||||
{
|
||||
if (pptr() == epptr())
|
||||
{
|
||||
std::size_t buffer_size = pptr() - gptr();
|
||||
if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta)
|
||||
{
|
||||
reserve(max_size_ - buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
reserve(buffer_delta);
|
||||
}
|
||||
}
|
||||
|
||||
*pptr() = traits_type::to_char_type(c);
|
||||
pbump(1);
|
||||
return c;
|
||||
}
|
||||
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
|
||||
void reserve(std::size_t n)
|
||||
{
|
||||
// Get current stream positions as offsets.
|
||||
std::size_t gnext = gptr() - &buffer_[0];
|
||||
std::size_t gend = egptr() - &buffer_[0];
|
||||
std::size_t pnext = pptr() - &buffer_[0];
|
||||
std::size_t pend = epptr() - &buffer_[0];
|
||||
|
||||
// Check if there is already enough space in the put area.
|
||||
if (n <= pend - pnext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Shift existing contents of get area to start of buffer.
|
||||
if (gnext > 0)
|
||||
{
|
||||
std::rotate(&buffer_[0], &buffer_[0] + gnext, &buffer_[0] + pend);
|
||||
gend -= gnext;
|
||||
pnext -= gnext;
|
||||
}
|
||||
|
||||
// Ensure buffer is large enough to hold at least the specified size.
|
||||
if (n > pend - pnext)
|
||||
{
|
||||
if (n <= max_size_ && pnext <= max_size_ - n)
|
||||
{
|
||||
buffer_.resize((std::max<std::size_t>)(pnext + n, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::length_error("asio::streambuf too long");
|
||||
}
|
||||
}
|
||||
|
||||
// Update stream positions.
|
||||
setg(&buffer_[0], &buffer_[0], &buffer_[0] + gend);
|
||||
setp(&buffer_[0] + pnext, &buffer_[0] + pnext + n);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t max_size_;
|
||||
std::vector<char_type, Allocator> buffer_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BASIC_STREAMBUF_HPP
|
790
libtorrent/include/asio/buffer.hpp
Normal file
|
@ -0,0 +1,790 @@
|
|||
//
|
||||
// buffer.hpp
|
||||
// ~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFER_HPP
|
||||
#define ASIO_BUFFER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# if defined(_HAS_ITERATOR_DEBUGGING)
|
||||
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
# endif // defined(_HAS_ITERATOR_DEBUGGING)
|
||||
#endif // defined(BOOST_MSVC)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# if defined(_GLIBCXX_DEBUG)
|
||||
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
# endif // defined(_GLIBCXX_DEBUG)
|
||||
#endif // defined(__GNUC__)
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
# include "asio/detail/push_options.hpp"
|
||||
# include <boost/function.hpp>
|
||||
# include "asio/detail/pop_options.hpp"
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
|
||||
namespace asio {
|
||||
|
||||
class mutable_buffer;
|
||||
class const_buffer;
|
||||
|
||||
namespace detail {
|
||||
void* buffer_cast_helper(const mutable_buffer&);
|
||||
const void* buffer_cast_helper(const const_buffer&);
|
||||
std::size_t buffer_size_helper(const mutable_buffer&);
|
||||
std::size_t buffer_size_helper(const const_buffer&);
|
||||
} // namespace detail
|
||||
|
||||
/// Holds a buffer that can be modified.
|
||||
/**
|
||||
* The mutable_buffer class provides a safe representation of a buffer that can
|
||||
* be modified. It does not own the underlying data, and so is cheap to copy or
|
||||
* assign.
|
||||
*/
|
||||
class mutable_buffer
|
||||
{
|
||||
public:
|
||||
/// Construct an empty buffer.
|
||||
mutable_buffer()
|
||||
: data_(0),
|
||||
size_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a buffer to represent a given memory range.
|
||||
mutable_buffer(void* data, std::size_t size)
|
||||
: data_(data),
|
||||
size_(size)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
mutable_buffer(void* data, std::size_t size,
|
||||
boost::function<void()> debug_check)
|
||||
: data_(data),
|
||||
size_(size),
|
||||
debug_check_(debug_check)
|
||||
{
|
||||
}
|
||||
|
||||
const boost::function<void()>& get_debug_check() const
|
||||
{
|
||||
return debug_check_;
|
||||
}
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
|
||||
private:
|
||||
friend void* asio::detail::buffer_cast_helper(
|
||||
const mutable_buffer& b);
|
||||
friend std::size_t asio::detail::buffer_size_helper(
|
||||
const mutable_buffer& b);
|
||||
|
||||
void* data_;
|
||||
std::size_t size_;
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
boost::function<void()> debug_check_;
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline void* buffer_cast_helper(const mutable_buffer& b)
|
||||
{
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
if (b.size_ && b.debug_check_)
|
||||
b.debug_check_();
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
return b.data_;
|
||||
}
|
||||
|
||||
inline std::size_t buffer_size_helper(const mutable_buffer& b)
|
||||
{
|
||||
return b.size_;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Cast a non-modifiable buffer to a specified pointer to POD type.
|
||||
/**
|
||||
* @relates mutable_buffer
|
||||
*/
|
||||
template <typename PointerToPodType>
|
||||
inline PointerToPodType buffer_cast(const mutable_buffer& b)
|
||||
{
|
||||
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
||||
}
|
||||
|
||||
/// Get the number of bytes in a non-modifiable buffer.
|
||||
/**
|
||||
* @relates mutable_buffer
|
||||
*/
|
||||
inline std::size_t buffer_size(const mutable_buffer& b)
|
||||
{
|
||||
return detail::buffer_size_helper(b);
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that is offset from the start of another.
|
||||
/**
|
||||
* @relates mutable_buffer
|
||||
*/
|
||||
inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
|
||||
{
|
||||
if (start > buffer_size(b))
|
||||
return mutable_buffer();
|
||||
char* new_data = buffer_cast<char*>(b) + start;
|
||||
std::size_t new_size = buffer_size(b) - start;
|
||||
return mutable_buffer(new_data, new_size
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that is offset from the start of another.
|
||||
/**
|
||||
* @relates mutable_buffer
|
||||
*/
|
||||
inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
|
||||
{
|
||||
if (start > buffer_size(b))
|
||||
return mutable_buffer();
|
||||
char* new_data = buffer_cast<char*>(b) + start;
|
||||
std::size_t new_size = buffer_size(b) - start;
|
||||
return mutable_buffer(new_data, new_size
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
/// Adapts a single modifiable buffer so that it meets the requirements of the
|
||||
/// MutableBufferSequence concept.
|
||||
class mutable_buffers_1
|
||||
: public mutable_buffer
|
||||
{
|
||||
public:
|
||||
/// The type for each element in the list of buffers.
|
||||
typedef mutable_buffer value_type;
|
||||
|
||||
/// A random-access iterator type that may be used to read elements.
|
||||
typedef const mutable_buffer* const_iterator;
|
||||
|
||||
/// Construct to represent a single modifiable buffer.
|
||||
explicit mutable_buffers_1(const mutable_buffer& b)
|
||||
: mutable_buffer(b)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get a random-access iterator to the first element.
|
||||
const_iterator begin() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Get a random-access iterator for one past the last element.
|
||||
const_iterator end() const
|
||||
{
|
||||
return begin() + 1;
|
||||
}
|
||||
};
|
||||
|
||||
/// Holds a buffer that cannot be modified.
|
||||
/**
|
||||
* The const_buffer class provides a safe representation of a buffer that cannot
|
||||
* be modified. It does not own the underlying data, and so is cheap to copy or
|
||||
* assign.
|
||||
*/
|
||||
class const_buffer
|
||||
{
|
||||
public:
|
||||
/// Construct an empty buffer.
|
||||
const_buffer()
|
||||
: data_(0),
|
||||
size_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a buffer to represent a given memory range.
|
||||
const_buffer(const void* data, std::size_t size)
|
||||
: data_(data),
|
||||
size_(size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a non-modifiable buffer from a modifiable one.
|
||||
const_buffer(const mutable_buffer& b)
|
||||
: data_(asio::detail::buffer_cast_helper(b)),
|
||||
size_(asio::detail::buffer_size_helper(b))
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, debug_check_(b.get_debug_check())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
const_buffer(const void* data, std::size_t size,
|
||||
boost::function<void()> debug_check)
|
||||
: data_(data),
|
||||
size_(size),
|
||||
debug_check_(debug_check)
|
||||
{
|
||||
}
|
||||
|
||||
const boost::function<void()>& get_debug_check() const
|
||||
{
|
||||
return debug_check_;
|
||||
}
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
|
||||
private:
|
||||
friend const void* asio::detail::buffer_cast_helper(
|
||||
const const_buffer& b);
|
||||
friend std::size_t asio::detail::buffer_size_helper(
|
||||
const const_buffer& b);
|
||||
|
||||
const void* data_;
|
||||
std::size_t size_;
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
boost::function<void()> debug_check_;
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline const void* buffer_cast_helper(const const_buffer& b)
|
||||
{
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
if (b.size_ && b.debug_check_)
|
||||
b.debug_check_();
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
return b.data_;
|
||||
}
|
||||
|
||||
inline std::size_t buffer_size_helper(const const_buffer& b)
|
||||
{
|
||||
return b.size_;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Cast a non-modifiable buffer to a specified pointer to POD type.
|
||||
/**
|
||||
* @relates const_buffer
|
||||
*/
|
||||
template <typename PointerToPodType>
|
||||
inline PointerToPodType buffer_cast(const const_buffer& b)
|
||||
{
|
||||
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
||||
}
|
||||
|
||||
/// Get the number of bytes in a non-modifiable buffer.
|
||||
/**
|
||||
* @relates const_buffer
|
||||
*/
|
||||
inline std::size_t buffer_size(const const_buffer& b)
|
||||
{
|
||||
return detail::buffer_size_helper(b);
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that is offset from the start of another.
|
||||
/**
|
||||
* @relates const_buffer
|
||||
*/
|
||||
inline const_buffer operator+(const const_buffer& b, std::size_t start)
|
||||
{
|
||||
if (start > buffer_size(b))
|
||||
return const_buffer();
|
||||
const char* new_data = buffer_cast<const char*>(b) + start;
|
||||
std::size_t new_size = buffer_size(b) - start;
|
||||
return const_buffer(new_data, new_size
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that is offset from the start of another.
|
||||
/**
|
||||
* @relates const_buffer
|
||||
*/
|
||||
inline const_buffer operator+(std::size_t start, const const_buffer& b)
|
||||
{
|
||||
if (start > buffer_size(b))
|
||||
return const_buffer();
|
||||
const char* new_data = buffer_cast<const char*>(b) + start;
|
||||
std::size_t new_size = buffer_size(b) - start;
|
||||
return const_buffer(new_data, new_size
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
/// Adapts a single non-modifiable buffer so that it meets the requirements of
|
||||
/// the ConstBufferSequence concept.
|
||||
class const_buffers_1
|
||||
: public const_buffer
|
||||
{
|
||||
public:
|
||||
/// The type for each element in the list of buffers.
|
||||
typedef const_buffer value_type;
|
||||
|
||||
/// A random-access iterator type that may be used to read elements.
|
||||
typedef const const_buffer* const_iterator;
|
||||
|
||||
/// Construct to represent a single non-modifiable buffer.
|
||||
explicit const_buffers_1(const const_buffer& b)
|
||||
: const_buffer(b)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get a random-access iterator to the first element.
|
||||
const_iterator begin() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Get a random-access iterator for one past the last element.
|
||||
const_iterator end() const
|
||||
{
|
||||
return begin() + 1;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
namespace detail {
|
||||
|
||||
template <typename Iterator>
|
||||
class buffer_debug_check
|
||||
{
|
||||
public:
|
||||
buffer_debug_check(Iterator iter)
|
||||
: iter_(iter)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
*iter_;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator iter_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
|
||||
/** @defgroup buffer asio::buffer
|
||||
*
|
||||
* @brief The asio::buffer function is used to create a buffer object to
|
||||
* represent raw memory, an array of POD elements, or a vector of POD elements.
|
||||
*
|
||||
* The simplest use case involves reading or writing a single buffer of a
|
||||
* specified size:
|
||||
*
|
||||
* @code sock.write(asio::buffer(data, size)); @endcode
|
||||
*
|
||||
* In the above example, the return value of asio::buffer meets the
|
||||
* requirements of the ConstBufferSequence concept so that it may be directly
|
||||
* passed to the socket's write function. A buffer created for modifiable
|
||||
* memory also meets the requirements of the MutableBufferSequence concept.
|
||||
*
|
||||
* An individual buffer may be created from a builtin array, std::vector or
|
||||
* boost::array of POD elements. This helps prevent buffer overruns by
|
||||
* automatically determining the size of the buffer:
|
||||
*
|
||||
* @code char d1[128];
|
||||
* size_t bytes_transferred = sock.read(asio::buffer(d1));
|
||||
*
|
||||
* std::vector<char> d2(128);
|
||||
* bytes_transferred = sock.read(asio::buffer(d2));
|
||||
*
|
||||
* boost::array<char, 128> d3;
|
||||
* bytes_transferred = sock.read(asio::buffer(d3)); @endcode
|
||||
*
|
||||
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
|
||||
* buffer objects may be assigned into a container that supports the
|
||||
* MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
|
||||
*
|
||||
* @code
|
||||
* char d1[128];
|
||||
* std::vector<char> d2(128);
|
||||
* boost::array<char, 128> d3;
|
||||
*
|
||||
* boost::array<mutable_buffer, 3> bufs1 = {
|
||||
* asio::buffer(d1),
|
||||
* asio::buffer(d2),
|
||||
* asio::buffer(d3) };
|
||||
* bytes_transferred = sock.read(bufs1);
|
||||
*
|
||||
* std::vector<const_buffer> bufs2;
|
||||
* bufs2.push_back(asio::buffer(d1));
|
||||
* bufs2.push_back(asio::buffer(d2));
|
||||
* bufs2.push_back(asio::buffer(d3));
|
||||
* bytes_transferred = sock.write(bufs2); @endcode
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/// Create a new modifiable buffer from an existing buffer.
|
||||
inline mutable_buffers_1 buffer(const mutable_buffer& b)
|
||||
{
|
||||
return mutable_buffers_1(b);
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer from an existing buffer.
|
||||
inline mutable_buffers_1 buffer(const mutable_buffer& b,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(buffer_cast<void*>(b),
|
||||
buffer_size(b) < max_size_in_bytes
|
||||
? buffer_size(b) : max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer from an existing buffer.
|
||||
inline const_buffers_1 buffer(const const_buffer& b)
|
||||
{
|
||||
return const_buffers_1(b);
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer from an existing buffer.
|
||||
inline const_buffers_1 buffer(const const_buffer& b,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(buffer_cast<const void*>(b),
|
||||
buffer_size(b) < max_size_in_bytes
|
||||
? buffer_size(b) : max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, b.get_debug_check()
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given memory range.
|
||||
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
|
||||
{
|
||||
return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given memory range.
|
||||
inline const_buffers_1 buffer(const void* data,
|
||||
std::size_t size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(const_buffer(data, size_in_bytes));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline mutable_buffers_1 buffer(PodType (&data)[N])
|
||||
{
|
||||
return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline mutable_buffers_1 buffer(PodType (&data)[N],
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(data,
|
||||
N * sizeof(PodType) < max_size_in_bytes
|
||||
? N * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(const PodType (&data)[N])
|
||||
{
|
||||
return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(const PodType (&data)[N],
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data,
|
||||
N * sizeof(PodType) < max_size_in_bytes
|
||||
? N * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
|
||||
// Borland C++ thinks the overloads:
|
||||
//
|
||||
// unspecified buffer(boost::array<PodType, N>& array ...);
|
||||
//
|
||||
// and
|
||||
//
|
||||
// unspecified buffer(boost::array<const PodType, N>& array ...);
|
||||
//
|
||||
// are ambiguous. This will be worked around by using a buffer_types traits
|
||||
// class that contains typedefs for the appropriate buffer and container
|
||||
// classes, based on whether PodType is const or non-const.
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <bool IsConst>
|
||||
struct buffer_types_base;
|
||||
|
||||
template <>
|
||||
struct buffer_types_base<false>
|
||||
{
|
||||
typedef mutable_buffer buffer_type;
|
||||
typedef mutable_buffers_1 container_type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct buffer_types_base<true>
|
||||
{
|
||||
typedef const_buffer buffer_type;
|
||||
typedef const_buffers_1 container_type;
|
||||
};
|
||||
|
||||
template <typename PodType>
|
||||
struct buffer_types
|
||||
: public buffer_types_base<boost::is_const<PodType>::value>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename PodType, std::size_t N>
|
||||
inline typename detail::buffer_types<PodType>::container_type
|
||||
buffer(boost::array<PodType, N>& data)
|
||||
{
|
||||
typedef typename asio::detail::buffer_types<PodType>::buffer_type
|
||||
buffer_type;
|
||||
typedef typename asio::detail::buffer_types<PodType>::container_type
|
||||
container_type;
|
||||
return container_type(
|
||||
buffer_type(data.c_array(), data.size() * sizeof(PodType)));
|
||||
}
|
||||
|
||||
template <typename PodType, std::size_t N>
|
||||
inline typename detail::buffer_types<PodType>::container_type
|
||||
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
|
||||
{
|
||||
typedef typename asio::detail::buffer_types<PodType>::buffer_type
|
||||
buffer_type;
|
||||
typedef typename asio::detail::buffer_types<PodType>::container_type
|
||||
container_type;
|
||||
return container_type(
|
||||
buffer_type(data.c_array(),
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(data.c_array(),
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data.data(), data.size() * sizeof(PodType)));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data.data(),
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data.data(), data.size() * sizeof(PodType)));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data.data(),
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD vector.
|
||||
/**
|
||||
* @note The buffer is invalidated by any vector operation that would also
|
||||
* invalidate iterators.
|
||||
*/
|
||||
template <typename PodType, typename Allocator>
|
||||
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(&data[0], data.size() * sizeof(PodType)
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<
|
||||
typename std::vector<PodType, Allocator>::iterator
|
||||
>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD vector.
|
||||
/**
|
||||
* @note The buffer is invalidated by any vector operation that would also
|
||||
* invalidate iterators.
|
||||
*/
|
||||
template <typename PodType, typename Allocator>
|
||||
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return mutable_buffers_1(
|
||||
mutable_buffer(&data[0],
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<
|
||||
typename std::vector<PodType, Allocator>::iterator
|
||||
>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD vector.
|
||||
/**
|
||||
* @note The buffer is invalidated by any vector operation that would also
|
||||
* invalidate iterators.
|
||||
*/
|
||||
template <typename PodType, typename Allocator>
|
||||
inline const_buffers_1 buffer(
|
||||
const std::vector<PodType, Allocator>& data)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(&data[0], data.size() * sizeof(PodType)
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<
|
||||
typename std::vector<PodType, Allocator>::const_iterator
|
||||
>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD vector.
|
||||
/**
|
||||
* @note The buffer is invalidated by any vector operation that would also
|
||||
* invalidate iterators.
|
||||
*/
|
||||
template <typename PodType, typename Allocator>
|
||||
inline const_buffers_1 buffer(
|
||||
const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(&data[0],
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
? data.size() * sizeof(PodType) : max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<
|
||||
typename std::vector<PodType, Allocator>::const_iterator
|
||||
>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given string.
|
||||
/**
|
||||
* @note The buffer is invalidated by any non-const operation called on the
|
||||
* given string object.
|
||||
*/
|
||||
inline const_buffers_1 buffer(const std::string& data)
|
||||
{
|
||||
return const_buffers_1(const_buffer(data.data(), data.size()
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given string.
|
||||
/**
|
||||
* @note The buffer is invalidated by any non-const operation called on the
|
||||
* given string object.
|
||||
*/
|
||||
inline const_buffers_1 buffer(const std::string& data,
|
||||
std::size_t max_size_in_bytes)
|
||||
{
|
||||
return const_buffers_1(
|
||||
const_buffer(data.data(),
|
||||
data.size() < max_size_in_bytes
|
||||
? data.size() : max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
));
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFER_HPP
|
407
libtorrent/include/asio/buffered_read_stream.hpp
Normal file
|
@ -0,0 +1,407 @@
|
|||
//
|
||||
// buffered_read_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_READ_STREAM_HPP
|
||||
#define ASIO_BUFFERED_READ_STREAM_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffered_read_stream_fwd.hpp"
|
||||
#include "asio/buffer.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/buffer_resize_guard.hpp"
|
||||
#include "asio/detail/buffered_stream_storage.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Adds buffering to the read-related operations of a stream.
|
||||
/**
|
||||
* The buffered_read_stream class template can be used to add buffering to the
|
||||
* synchronous and asynchronous read operations of a stream.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Stream>
|
||||
class buffered_read_stream
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The type of the next layer.
|
||||
typedef typename boost::remove_reference<Stream>::type next_layer_type;
|
||||
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The default buffer size.
|
||||
static const std::size_t default_buffer_size = implementation_defined;
|
||||
#else
|
||||
BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
|
||||
#endif
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
explicit buffered_read_stream(Arg& a)
|
||||
: next_layer_(a),
|
||||
storage_(default_buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
buffered_read_stream(Arg& a, std::size_t buffer_size)
|
||||
: next_layer_(a),
|
||||
storage_(buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return next_layer_;
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
asio::io_service& io_service()
|
||||
{
|
||||
return next_layer_.io_service();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
void close()
|
||||
{
|
||||
next_layer_.close();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.close(ec);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written.
|
||||
/// Throws an exception on failure.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
return next_layer_.write_some(buffers);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written,
|
||||
/// or 0 if an error occurred.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.write_some(buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write. The data being written must be valid for the
|
||||
/// lifetime of the asynchronous operation.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence& buffers,
|
||||
WriteHandler handler)
|
||||
{
|
||||
next_layer_.async_write_some(buffers, handler);
|
||||
}
|
||||
|
||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||
/// buffer as a result of the operation. Throws an exception on failure.
|
||||
std::size_t fill()
|
||||
{
|
||||
detail::buffer_resize_guard<detail::buffered_stream_storage>
|
||||
resize_guard(storage_);
|
||||
std::size_t previous_size = storage_.size();
|
||||
storage_.resize(storage_.capacity());
|
||||
storage_.resize(previous_size + next_layer_.read_some(buffer(
|
||||
storage_.data() + previous_size,
|
||||
storage_.size() - previous_size)));
|
||||
resize_guard.commit();
|
||||
return storage_.size() - previous_size;
|
||||
}
|
||||
|
||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||
/// buffer as a result of the operation, or 0 if an error occurred.
|
||||
std::size_t fill(asio::error_code& ec)
|
||||
{
|
||||
detail::buffer_resize_guard<detail::buffered_stream_storage>
|
||||
resize_guard(storage_);
|
||||
std::size_t previous_size = storage_.size();
|
||||
storage_.resize(storage_.capacity());
|
||||
storage_.resize(previous_size + next_layer_.read_some(buffer(
|
||||
storage_.data() + previous_size,
|
||||
storage_.size() - previous_size),
|
||||
ec));
|
||||
resize_guard.commit();
|
||||
return storage_.size() - previous_size;
|
||||
}
|
||||
|
||||
template <typename ReadHandler>
|
||||
class fill_handler
|
||||
{
|
||||
public:
|
||||
fill_handler(asio::io_service& io_service,
|
||||
detail::buffered_stream_storage& storage,
|
||||
std::size_t previous_size, ReadHandler handler)
|
||||
: io_service_(io_service),
|
||||
storage_(storage),
|
||||
previous_size_(previous_size),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& ec,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
storage_.resize(previous_size_ + bytes_transferred);
|
||||
io_service_.dispatch(detail::bind_handler(
|
||||
handler_, ec, bytes_transferred));
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_service& io_service_;
|
||||
detail::buffered_stream_storage& storage_;
|
||||
std::size_t previous_size_;
|
||||
ReadHandler handler_;
|
||||
};
|
||||
|
||||
/// Start an asynchronous fill.
|
||||
template <typename ReadHandler>
|
||||
void async_fill(ReadHandler handler)
|
||||
{
|
||||
std::size_t previous_size = storage_.size();
|
||||
storage_.resize(storage_.capacity());
|
||||
next_layer_.async_read_some(
|
||||
buffer(
|
||||
storage_.data() + previous_size,
|
||||
storage_.size() - previous_size),
|
||||
fill_handler<ReadHandler>(io_service(),
|
||||
storage_, previous_size, handler));
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||
/// an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
if (storage_.empty())
|
||||
fill();
|
||||
return copy(buffers);
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||
/// an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
if (storage_.empty() && !fill(ec))
|
||||
return 0;
|
||||
return copy(buffers);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
class read_some_handler
|
||||
{
|
||||
public:
|
||||
read_some_handler(asio::io_service& io_service,
|
||||
detail::buffered_stream_storage& storage,
|
||||
const MutableBufferSequence& buffers, ReadHandler handler)
|
||||
: io_service_(io_service),
|
||||
storage_(storage),
|
||||
buffers_(buffers),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& ec, std::size_t)
|
||||
{
|
||||
if (ec || storage_.empty())
|
||||
{
|
||||
std::size_t length = 0;
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
|
||||
std::size_t bytes_avail = storage_.size();
|
||||
std::size_t bytes_copied = 0;
|
||||
|
||||
typename MutableBufferSequence::const_iterator iter = buffers_.begin();
|
||||
typename MutableBufferSequence::const_iterator end = buffers_.end();
|
||||
for (; iter != end && bytes_avail > 0; ++iter)
|
||||
{
|
||||
std::size_t max_length = buffer_size(*iter);
|
||||
std::size_t length = (max_length < bytes_avail)
|
||||
? max_length : bytes_avail;
|
||||
memcpy(buffer_cast<void*>(*iter),
|
||||
storage_.data() + bytes_copied, length);
|
||||
bytes_copied += length;
|
||||
bytes_avail -= length;
|
||||
}
|
||||
|
||||
storage_.consume(bytes_copied);
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_service& io_service_;
|
||||
detail::buffered_stream_storage& storage_;
|
||||
MutableBufferSequence buffers_;
|
||||
ReadHandler handler_;
|
||||
};
|
||||
|
||||
/// Start an asynchronous read. The buffer into which the data will be read
|
||||
/// must be valid for the lifetime of the asynchronous operation.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence& buffers,
|
||||
ReadHandler handler)
|
||||
{
|
||||
if (storage_.empty())
|
||||
{
|
||||
async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
|
||||
io_service(), storage_, buffers, handler));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t length = copy(buffers);
|
||||
io_service().post(detail::bind_handler(
|
||||
handler, asio::error_code(), length));
|
||||
}
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||
/// Throws an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers)
|
||||
{
|
||||
if (storage_.empty())
|
||||
fill();
|
||||
return peek_copy(buffers);
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||
/// or 0 if an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
if (storage_.empty() && !fill(ec))
|
||||
return 0;
|
||||
return peek_copy(buffers);
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail()
|
||||
{
|
||||
return storage_.size();
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail(asio::error_code& ec)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
return storage_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
/// Copy data out of the internal buffer to the specified target buffer.
|
||||
/// Returns the number of bytes copied.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t copy(const MutableBufferSequence& buffers)
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
|
||||
std::size_t bytes_avail = storage_.size();
|
||||
std::size_t bytes_copied = 0;
|
||||
|
||||
typename MutableBufferSequence::const_iterator iter = buffers.begin();
|
||||
typename MutableBufferSequence::const_iterator end = buffers.end();
|
||||
for (; iter != end && bytes_avail > 0; ++iter)
|
||||
{
|
||||
std::size_t max_length = buffer_size(*iter);
|
||||
std::size_t length = (max_length < bytes_avail)
|
||||
? max_length : bytes_avail;
|
||||
memcpy(buffer_cast<void*>(*iter), storage_.data() + bytes_copied, length);
|
||||
bytes_copied += length;
|
||||
bytes_avail -= length;
|
||||
}
|
||||
|
||||
storage_.consume(bytes_copied);
|
||||
return bytes_copied;
|
||||
}
|
||||
|
||||
/// Copy data from the internal buffer to the specified target buffer, without
|
||||
/// removing the data from the internal buffer. Returns the number of bytes
|
||||
/// copied.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek_copy(const MutableBufferSequence& buffers)
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
|
||||
std::size_t bytes_avail = storage_.size();
|
||||
std::size_t bytes_copied = 0;
|
||||
|
||||
typename MutableBufferSequence::const_iterator iter = buffers.begin();
|
||||
typename MutableBufferSequence::const_iterator end = buffers.end();
|
||||
for (; iter != end && bytes_avail > 0; ++iter)
|
||||
{
|
||||
std::size_t max_length = buffer_size(*iter);
|
||||
std::size_t length = (max_length < bytes_avail)
|
||||
? max_length : bytes_avail;
|
||||
memcpy(buffer_cast<void*>(*iter), storage_.data() + bytes_copied, length);
|
||||
bytes_copied += length;
|
||||
bytes_avail -= length;
|
||||
}
|
||||
|
||||
return bytes_copied;
|
||||
}
|
||||
|
||||
/// The next layer.
|
||||
Stream next_layer_;
|
||||
|
||||
// The data in the buffer.
|
||||
detail::buffered_stream_storage storage_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_READ_STREAM_HPP
|
29
libtorrent/include/asio/buffered_read_stream_fwd.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// buffered_read_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_READ_STREAM_FWD_HPP
|
||||
#define ASIO_BUFFERED_READ_STREAM_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
template <typename Stream>
|
||||
class buffered_read_stream;
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_READ_STREAM_FWD_HPP
|
243
libtorrent/include/asio/buffered_stream.hpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
//
|
||||
// buffered_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_STREAM_HPP
|
||||
#define ASIO_BUFFERED_STREAM_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffered_read_stream.hpp"
|
||||
#include "asio/buffered_write_stream.hpp"
|
||||
#include "asio/buffered_stream_fwd.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Adds buffering to the read- and write-related operations of a stream.
|
||||
/**
|
||||
* The buffered_stream class template can be used to add buffering to the
|
||||
* synchronous and asynchronous read and write operations of a stream.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Stream>
|
||||
class buffered_stream
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The type of the next layer.
|
||||
typedef typename boost::remove_reference<Stream>::type next_layer_type;
|
||||
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
explicit buffered_stream(Arg& a)
|
||||
: inner_stream_impl_(a),
|
||||
stream_impl_(inner_stream_impl_)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
explicit buffered_stream(Arg& a, std::size_t read_buffer_size,
|
||||
std::size_t write_buffer_size)
|
||||
: inner_stream_impl_(a, write_buffer_size),
|
||||
stream_impl_(inner_stream_impl_, read_buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return stream_impl_.next_layer().next_layer();
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return stream_impl_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
asio::io_service& io_service()
|
||||
{
|
||||
return stream_impl_.io_service();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
void close()
|
||||
{
|
||||
stream_impl_.close();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.close(ec);
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
/// bytes written to the next layer on the last write operation. Throws an
|
||||
/// exception on failure.
|
||||
std::size_t flush()
|
||||
{
|
||||
return stream_impl_.next_layer().flush();
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
/// bytes written to the next layer on the last write operation, or 0 if an
|
||||
/// error occurred.
|
||||
std::size_t flush(asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.next_layer().flush(ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous flush.
|
||||
template <typename WriteHandler>
|
||||
void async_flush(WriteHandler handler)
|
||||
{
|
||||
return stream_impl_.next_layer().async_flush(handler);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written.
|
||||
/// Throws an exception on failure.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
return stream_impl_.write_some(buffers);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written,
|
||||
/// or 0 if an error occurred.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.write_some(buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous write. The data being written must be valid for the
|
||||
/// lifetime of the asynchronous operation.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence& buffers,
|
||||
WriteHandler handler)
|
||||
{
|
||||
stream_impl_.async_write_some(buffers, handler);
|
||||
}
|
||||
|
||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||
/// buffer as a result of the operation. Throws an exception on failure.
|
||||
std::size_t fill()
|
||||
{
|
||||
return stream_impl_.fill();
|
||||
}
|
||||
|
||||
/// Fill the buffer with some data. Returns the number of bytes placed in the
|
||||
/// buffer as a result of the operation, or 0 if an error occurred.
|
||||
std::size_t fill(asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.fill(ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous fill.
|
||||
template <typename ReadHandler>
|
||||
void async_fill(ReadHandler handler)
|
||||
{
|
||||
stream_impl_.async_fill(handler);
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||
/// an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
return stream_impl_.read_some(buffers);
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||
/// an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.read_some(buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read. The buffer into which the data will be read
|
||||
/// must be valid for the lifetime of the asynchronous operation.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence& buffers,
|
||||
ReadHandler handler)
|
||||
{
|
||||
stream_impl_.async_read_some(buffers, handler);
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||
/// Throws an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers)
|
||||
{
|
||||
return stream_impl_.peek(buffers);
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||
/// or 0 if an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.peek(buffers, ec);
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail()
|
||||
{
|
||||
return stream_impl_.in_avail();
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail(asio::error_code& ec)
|
||||
{
|
||||
return stream_impl_.in_avail(ec);
|
||||
}
|
||||
|
||||
private:
|
||||
// The buffered write stream.
|
||||
typedef buffered_write_stream<Stream> write_stream_type;
|
||||
write_stream_type inner_stream_impl_;
|
||||
|
||||
// The buffered read stream.
|
||||
typedef buffered_read_stream<write_stream_type&> read_stream_type;
|
||||
read_stream_type stream_impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_STREAM_HPP
|
29
libtorrent/include/asio/buffered_stream_fwd.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// buffered_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_STREAM_FWD_HPP
|
||||
#define ASIO_BUFFERED_STREAM_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
template <typename Stream>
|
||||
class buffered_stream;
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_STREAM_FWD_HPP
|
361
libtorrent/include/asio/buffered_write_stream.hpp
Normal file
|
@ -0,0 +1,361 @@
|
|||
//
|
||||
// buffered_write_stream.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_WRITE_STREAM_HPP
|
||||
#define ASIO_BUFFERED_WRITE_STREAM_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffered_write_stream_fwd.hpp"
|
||||
#include "asio/buffer.hpp"
|
||||
#include "asio/completion_condition.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/write.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/buffered_stream_storage.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Adds buffering to the write-related operations of a stream.
|
||||
/**
|
||||
* The buffered_write_stream class template can be used to add buffering to the
|
||||
* synchronous and asynchronous write operations of a stream.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* @e Distinct @e objects: Safe.@n
|
||||
* @e Shared @e objects: Unsafe.
|
||||
*
|
||||
* @par Concepts:
|
||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||
*/
|
||||
template <typename Stream>
|
||||
class buffered_write_stream
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
/// The type of the next layer.
|
||||
typedef typename boost::remove_reference<Stream>::type next_layer_type;
|
||||
|
||||
/// The type of the lowest layer.
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The default buffer size.
|
||||
static const std::size_t default_buffer_size = implementation_defined;
|
||||
#else
|
||||
BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
|
||||
#endif
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
explicit buffered_write_stream(Arg& a)
|
||||
: next_layer_(a),
|
||||
storage_(default_buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct, passing the specified argument to initialise the next layer.
|
||||
template <typename Arg>
|
||||
buffered_write_stream(Arg& a, std::size_t buffer_size)
|
||||
: next_layer_(a),
|
||||
storage_(buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get a reference to the next layer.
|
||||
next_layer_type& next_layer()
|
||||
{
|
||||
return next_layer_;
|
||||
}
|
||||
|
||||
/// Get a reference to the lowest layer.
|
||||
lowest_layer_type& lowest_layer()
|
||||
{
|
||||
return next_layer_.lowest_layer();
|
||||
}
|
||||
|
||||
/// Get the io_service associated with the object.
|
||||
asio::io_service& io_service()
|
||||
{
|
||||
return next_layer_.io_service();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
void close()
|
||||
{
|
||||
next_layer_.close();
|
||||
}
|
||||
|
||||
/// Close the stream.
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.close(ec);
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
/// bytes written to the next layer on the last write operation. Throws an
|
||||
/// exception on failure.
|
||||
std::size_t flush()
|
||||
{
|
||||
std::size_t bytes_written = write(next_layer_,
|
||||
buffer(storage_.data(), storage_.size()));
|
||||
storage_.consume(bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
/// Flush all data from the buffer to the next layer. Returns the number of
|
||||
/// bytes written to the next layer on the last write operation, or 0 if an
|
||||
/// error occurred.
|
||||
std::size_t flush(asio::error_code& ec)
|
||||
{
|
||||
std::size_t bytes_written = write(next_layer_,
|
||||
buffer(storage_.data(), storage_.size()),
|
||||
transfer_all(), ec);
|
||||
storage_.consume(bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
template <typename WriteHandler>
|
||||
class flush_handler
|
||||
{
|
||||
public:
|
||||
flush_handler(asio::io_service& io_service,
|
||||
detail::buffered_stream_storage& storage, WriteHandler handler)
|
||||
: io_service_(io_service),
|
||||
storage_(storage),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& ec,
|
||||
std::size_t bytes_written)
|
||||
{
|
||||
storage_.consume(bytes_written);
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written));
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_service& io_service_;
|
||||
detail::buffered_stream_storage& storage_;
|
||||
WriteHandler handler_;
|
||||
};
|
||||
|
||||
/// Start an asynchronous flush.
|
||||
template <typename WriteHandler>
|
||||
void async_flush(WriteHandler handler)
|
||||
{
|
||||
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
|
||||
flush_handler<WriteHandler>(io_service(), storage_, handler));
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written.
|
||||
/// Throws an exception on failure.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||
{
|
||||
if (storage_.size() == storage_.capacity())
|
||||
flush();
|
||||
return copy(buffers);
|
||||
}
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written,
|
||||
/// or 0 if an error occurred and the error handler did not throw.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
if (storage_.size() == storage_.capacity() && !flush(ec))
|
||||
return 0;
|
||||
return copy(buffers);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
class write_some_handler
|
||||
{
|
||||
public:
|
||||
write_some_handler(asio::io_service& io_service,
|
||||
detail::buffered_stream_storage& storage,
|
||||
const ConstBufferSequence& buffers, WriteHandler handler)
|
||||
: io_service_(io_service),
|
||||
storage_(storage),
|
||||
buffers_(buffers),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& ec, std::size_t)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::size_t length = 0;
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, length));
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
|
||||
std::size_t orig_size = storage_.size();
|
||||
std::size_t space_avail = storage_.capacity() - orig_size;
|
||||
std::size_t bytes_copied = 0;
|
||||
|
||||
typename ConstBufferSequence::const_iterator iter = buffers_.begin();
|
||||
typename ConstBufferSequence::const_iterator end = buffers_.end();
|
||||
for (; iter != end && space_avail > 0; ++iter)
|
||||
{
|
||||
std::size_t bytes_avail = buffer_size(*iter);
|
||||
std::size_t length = (bytes_avail < space_avail)
|
||||
? bytes_avail : space_avail;
|
||||
storage_.resize(orig_size + bytes_copied + length);
|
||||
memcpy(storage_.data() + orig_size + bytes_copied,
|
||||
buffer_cast<const void*>(*iter), length);
|
||||
bytes_copied += length;
|
||||
space_avail -= length;
|
||||
}
|
||||
|
||||
io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_service& io_service_;
|
||||
detail::buffered_stream_storage& storage_;
|
||||
ConstBufferSequence buffers_;
|
||||
WriteHandler handler_;
|
||||
};
|
||||
|
||||
/// Start an asynchronous write. The data being written must be valid for the
|
||||
/// lifetime of the asynchronous operation.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence& buffers,
|
||||
WriteHandler handler)
|
||||
{
|
||||
if (storage_.size() == storage_.capacity())
|
||||
{
|
||||
async_flush(write_some_handler<ConstBufferSequence, WriteHandler>(
|
||||
io_service(), storage_, buffers, handler));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t bytes_copied = copy(buffers);
|
||||
io_service().post(detail::bind_handler(
|
||||
handler, asio::error_code(), bytes_copied));
|
||||
}
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read. Throws
|
||||
/// an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||
{
|
||||
return next_layer_.read_some(buffers);
|
||||
}
|
||||
|
||||
/// Read some data from the stream. Returns the number of bytes read or 0 if
|
||||
/// an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.read_some(buffers, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous read. The buffer into which the data will be read
|
||||
/// must be valid for the lifetime of the asynchronous operation.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence& buffers,
|
||||
ReadHandler handler)
|
||||
{
|
||||
next_layer_.async_read_some(buffers, handler);
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read.
|
||||
/// Throws an exception on failure.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers)
|
||||
{
|
||||
return next_layer_.peek(buffers);
|
||||
}
|
||||
|
||||
/// Peek at the incoming data on the stream. Returns the number of bytes read,
|
||||
/// or 0 if an error occurred.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t peek(const MutableBufferSequence& buffers,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.peek(buffers, ec);
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail()
|
||||
{
|
||||
return next_layer_.in_avail();
|
||||
}
|
||||
|
||||
/// Determine the amount of data that may be read without blocking.
|
||||
std::size_t in_avail(asio::error_code& ec)
|
||||
{
|
||||
return next_layer_.in_avail(ec);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Copy data into the internal buffer from the specified source buffer.
|
||||
/// Returns the number of bytes copied.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t copy(const ConstBufferSequence& buffers)
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
|
||||
std::size_t orig_size = storage_.size();
|
||||
std::size_t space_avail = storage_.capacity() - orig_size;
|
||||
std::size_t bytes_copied = 0;
|
||||
|
||||
typename ConstBufferSequence::const_iterator iter = buffers.begin();
|
||||
typename ConstBufferSequence::const_iterator end = buffers.end();
|
||||
for (; iter != end && space_avail > 0; ++iter)
|
||||
{
|
||||
std::size_t bytes_avail = buffer_size(*iter);
|
||||
std::size_t length = (bytes_avail < space_avail)
|
||||
? bytes_avail : space_avail;
|
||||
storage_.resize(orig_size + bytes_copied + length);
|
||||
memcpy(storage_.data() + orig_size + bytes_copied,
|
||||
buffer_cast<const void*>(*iter), length);
|
||||
bytes_copied += length;
|
||||
space_avail -= length;
|
||||
}
|
||||
|
||||
return bytes_copied;
|
||||
}
|
||||
|
||||
/// The next layer.
|
||||
Stream next_layer_;
|
||||
|
||||
// The data in the buffer.
|
||||
detail::buffered_stream_storage storage_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_WRITE_STREAM_HPP
|
29
libtorrent/include/asio/buffered_write_stream_fwd.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// buffered_write_stream_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_BUFFERED_WRITE_STREAM_FWD_HPP
|
||||
#define ASIO_BUFFERED_WRITE_STREAM_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
template <typename Stream>
|
||||
class buffered_write_stream;
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_BUFFERED_WRITE_STREAM_FWD_HPP
|
101
libtorrent/include/asio/completion_condition.hpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// completion_condition.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_COMPLETION_CONDITION_HPP
|
||||
#define ASIO_COMPLETION_CONDITION_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class transfer_all_t
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
template <typename Error>
|
||||
bool operator()(const Error& err, std::size_t)
|
||||
{
|
||||
return !!err;
|
||||
}
|
||||
};
|
||||
|
||||
class transfer_at_least_t
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
explicit transfer_at_least_t(std::size_t minimum)
|
||||
: minimum_(minimum)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Error>
|
||||
bool operator()(const Error& err, std::size_t bytes_transferred)
|
||||
{
|
||||
return !!err || bytes_transferred >= minimum_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t minimum_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @defgroup completion_condition Completion Condition Function Objects
|
||||
*
|
||||
* Function objects used for determining when a read or write operation should
|
||||
* complete.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until all of the data has been transferred,
|
||||
/// or until an error occurs.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_all();
|
||||
#else
|
||||
inline detail::transfer_all_t transfer_all()
|
||||
{
|
||||
return detail::transfer_all_t();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until a minimum number of bytes has been
|
||||
/// transferred, or until an error occurs.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_at_least(std::size_t minimum);
|
||||
#else
|
||||
inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum)
|
||||
{
|
||||
return detail::transfer_at_least_t(minimum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_COMPLETION_CONDITION_HPP
|
320
libtorrent/include/asio/datagram_socket_service.hpp
Normal file
|
@ -0,0 +1,320 @@
|
|||
//
|
||||
// datagram_socket_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DATAGRAM_SOCKET_SERVICE_HPP
|
||||
#define ASIO_DATAGRAM_SOCKET_SERVICE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/detail/epoll_reactor.hpp"
|
||||
#include "asio/detail/kqueue_reactor.hpp"
|
||||
#include "asio/detail/select_reactor.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
#include "asio/detail/reactive_socket_service.hpp"
|
||||
#include "asio/detail/win_iocp_socket_service.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Default service implementation for a datagram socket.
|
||||
template <typename Protocol>
|
||||
class datagram_socket_service
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
: public asio::io_service::service
|
||||
#else
|
||||
: public asio::detail::service_base<datagram_socket_service<Protocol> >
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The unique service identifier.
|
||||
static asio::io_service::id id;
|
||||
#endif
|
||||
|
||||
/// The protocol type.
|
||||
typedef Protocol protocol_type;
|
||||
|
||||
/// The endpoint type.
|
||||
typedef typename Protocol::endpoint endpoint_type;
|
||||
|
||||
private:
|
||||
// The type of the platform-specific implementation.
|
||||
#if defined(ASIO_HAS_IOCP)
|
||||
typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
|
||||
#elif defined(ASIO_HAS_EPOLL)
|
||||
typedef detail::reactive_socket_service<
|
||||
Protocol, detail::epoll_reactor<false> > service_impl_type;
|
||||
#elif defined(ASIO_HAS_KQUEUE)
|
||||
typedef detail::reactive_socket_service<
|
||||
Protocol, detail::kqueue_reactor<false> > service_impl_type;
|
||||
#else
|
||||
typedef detail::reactive_socket_service<
|
||||
Protocol, detail::select_reactor<false> > service_impl_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// The type of a datagram socket.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined implementation_type;
|
||||
#else
|
||||
typedef typename service_impl_type::implementation_type implementation_type;
|
||||
#endif
|
||||
|
||||
/// The native socket type.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined native_type;
|
||||
#else
|
||||
typedef typename service_impl_type::native_type native_type;
|
||||
#endif
|
||||
|
||||
/// Construct a new datagram socket service for the specified io_service.
|
||||
explicit datagram_socket_service(asio::io_service& io_service)
|
||||
: asio::detail::service_base<
|
||||
datagram_socket_service<Protocol> >(io_service),
|
||||
service_impl_(asio::use_service<service_impl_type>(io_service))
|
||||
{
|
||||
}
|
||||
|
||||
/// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a new datagram socket implementation.
|
||||
void construct(implementation_type& impl)
|
||||
{
|
||||
service_impl_.construct(impl);
|
||||
}
|
||||
|
||||
/// Destroy a datagram socket implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
service_impl_.destroy(impl);
|
||||
}
|
||||
|
||||
// Open a new datagram socket implementation.
|
||||
asio::error_code open(implementation_type& impl,
|
||||
const protocol_type& protocol, asio::error_code& ec)
|
||||
{
|
||||
if (protocol.type() == SOCK_DGRAM)
|
||||
service_impl_.open(impl, protocol, ec);
|
||||
else
|
||||
ec = asio::error::invalid_argument;
|
||||
return ec;
|
||||
}
|
||||
|
||||
/// Assign an existing native socket to a datagram socket.
|
||||
asio::error_code assign(implementation_type& impl,
|
||||
const protocol_type& protocol, const native_type& native_socket,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.assign(impl, protocol, native_socket, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is open.
|
||||
bool is_open(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.is_open(impl);
|
||||
}
|
||||
|
||||
/// Close a datagram socket implementation.
|
||||
asio::error_code close(implementation_type& impl,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.close(impl, ec);
|
||||
}
|
||||
|
||||
/// Get the native socket implementation.
|
||||
native_type native(implementation_type& impl)
|
||||
{
|
||||
return service_impl_.native(impl);
|
||||
}
|
||||
|
||||
/// Cancel all asynchronous operations associated with the socket.
|
||||
asio::error_code cancel(implementation_type& impl,
|
||||
asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.cancel(impl, ec);
|
||||
}
|
||||
|
||||
/// Determine whether the socket is at the out-of-band data mark.
|
||||
bool at_mark(const implementation_type& impl,
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
return service_impl_.at_mark(impl, ec);
|
||||
}
|
||||
|
||||
/// Determine the number of bytes available for reading.
|
||||
std::size_t available(const implementation_type& impl,
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
return service_impl_.available(impl, ec);
|
||||
}
|
||||
|
||||
// Bind the datagram socket to the specified local endpoint.
|
||||
asio::error_code bind(implementation_type& impl,
|
||||
const endpoint_type& endpoint, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.bind(impl, endpoint, ec);
|
||||
}
|
||||
|
||||
/// Connect the datagram socket to the specified endpoint.
|
||||
asio::error_code connect(implementation_type& impl,
|
||||
const endpoint_type& peer_endpoint, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.connect(impl, peer_endpoint, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous connect.
|
||||
template <typename ConnectHandler>
|
||||
void async_connect(implementation_type& impl,
|
||||
const endpoint_type& peer_endpoint, ConnectHandler handler)
|
||||
{
|
||||
service_impl_.async_connect(impl, peer_endpoint, handler);
|
||||
}
|
||||
|
||||
/// Set a socket option.
|
||||
template <typename SettableSocketOption>
|
||||
asio::error_code set_option(implementation_type& impl,
|
||||
const SettableSocketOption& option, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.set_option(impl, option, ec);
|
||||
}
|
||||
|
||||
/// Get a socket option.
|
||||
template <typename GettableSocketOption>
|
||||
asio::error_code get_option(const implementation_type& impl,
|
||||
GettableSocketOption& option, asio::error_code& ec) const
|
||||
{
|
||||
return service_impl_.get_option(impl, option, ec);
|
||||
}
|
||||
|
||||
/// Perform an IO control command on the socket.
|
||||
template <typename IoControlCommand>
|
||||
asio::error_code io_control(implementation_type& impl,
|
||||
IoControlCommand& command, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.io_control(impl, command, ec);
|
||||
}
|
||||
|
||||
/// Get the local endpoint.
|
||||
endpoint_type local_endpoint(const implementation_type& impl,
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
return service_impl_.local_endpoint(impl, ec);
|
||||
}
|
||||
|
||||
/// Get the remote endpoint.
|
||||
endpoint_type remote_endpoint(const implementation_type& impl,
|
||||
asio::error_code& ec) const
|
||||
{
|
||||
return service_impl_.remote_endpoint(impl, ec);
|
||||
}
|
||||
|
||||
/// Disable sends or receives on the socket.
|
||||
asio::error_code shutdown(implementation_type& impl,
|
||||
socket_base::shutdown_type what, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.shutdown(impl, what, ec);
|
||||
}
|
||||
|
||||
/// Send the given data to the peer.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.send(impl, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
|
||||
socket_base::message_flags flags, WriteHandler handler)
|
||||
{
|
||||
service_impl_.async_send(impl, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified endpoint.
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t send_to(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.send_to(impl, buffers, destination, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous send.
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_send_to(implementation_type& impl,
|
||||
const ConstBufferSequence& buffers, const endpoint_type& destination,
|
||||
socket_base::message_flags flags, WriteHandler handler)
|
||||
{
|
||||
service_impl_.async_send_to(impl, buffers, destination, flags, handler);
|
||||
}
|
||||
|
||||
/// Receive some data from the peer.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.receive(impl, buffers, flags, ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers,
|
||||
socket_base::message_flags flags, ReadHandler handler)
|
||||
{
|
||||
service_impl_.async_receive(impl, buffers, flags, handler);
|
||||
}
|
||||
|
||||
/// Receive a datagram with the endpoint of the sender.
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t receive_from(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||
socket_base::message_flags flags, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
|
||||
ec);
|
||||
}
|
||||
|
||||
/// Start an asynchronous receive that will get the endpoint of the sender.
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_receive_from(implementation_type& impl,
|
||||
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
|
||||
socket_base::message_flags flags, ReadHandler handler)
|
||||
{
|
||||
service_impl_.async_receive_from(impl, buffers, sender_endpoint, flags,
|
||||
handler);
|
||||
}
|
||||
|
||||
private:
|
||||
// The service that provides the platform-specific implementation.
|
||||
service_impl_type& service_impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DATAGRAM_SOCKET_SERVICE_HPP
|
37
libtorrent/include/asio/deadline_timer.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// deadline_timer.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DEADLINE_TIMER_HPP
|
||||
#define ASIO_DEADLINE_TIMER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/socket_types.hpp" // Must come before posix_time.
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/basic_deadline_timer.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Typedef for the typical usage of timer.
|
||||
typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DEADLINE_TIMER_HPP
|
164
libtorrent/include/asio/deadline_timer_service.hpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
//
|
||||
// deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DEADLINE_TIMER_SERVICE_HPP
|
||||
#define ASIO_DEADLINE_TIMER_SERVICE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/time_traits.hpp"
|
||||
#include "asio/detail/deadline_timer_service.hpp"
|
||||
#include "asio/detail/epoll_reactor.hpp"
|
||||
#include "asio/detail/kqueue_reactor.hpp"
|
||||
#include "asio/detail/select_reactor.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
/// Default service implementation for a timer.
|
||||
template <typename TimeType,
|
||||
typename TimeTraits = asio::time_traits<TimeType> >
|
||||
class deadline_timer_service
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
: public asio::io_service::service
|
||||
#else
|
||||
: public asio::detail::service_base<
|
||||
deadline_timer_service<TimeType, TimeTraits> >
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// The unique service identifier.
|
||||
static asio::io_service::id id;
|
||||
#endif
|
||||
|
||||
/// The time traits type.
|
||||
typedef TimeTraits traits_type;
|
||||
|
||||
/// The time type.
|
||||
typedef typename traits_type::time_type time_type;
|
||||
|
||||
/// The duration type.
|
||||
typedef typename traits_type::duration_type duration_type;
|
||||
|
||||
private:
|
||||
// The type of the platform-specific implementation.
|
||||
#if defined(ASIO_HAS_IOCP)
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::select_reactor<true> > service_impl_type;
|
||||
#elif defined(ASIO_HAS_EPOLL)
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::epoll_reactor<false> > service_impl_type;
|
||||
#elif defined(ASIO_HAS_KQUEUE)
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::kqueue_reactor<false> > service_impl_type;
|
||||
#else
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::select_reactor<false> > service_impl_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// The implementation type of the deadline timer.
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
typedef implementation_defined implementation_type;
|
||||
#else
|
||||
typedef typename service_impl_type::implementation_type implementation_type;
|
||||
#endif
|
||||
|
||||
/// Construct a new timer service for the specified io_service.
|
||||
explicit deadline_timer_service(asio::io_service& io_service)
|
||||
: asio::detail::service_base<
|
||||
deadline_timer_service<TimeType, TimeTraits> >(io_service),
|
||||
service_impl_(asio::use_service<service_impl_type>(io_service))
|
||||
{
|
||||
}
|
||||
|
||||
/// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a new timer implementation.
|
||||
void construct(implementation_type& impl)
|
||||
{
|
||||
service_impl_.construct(impl);
|
||||
}
|
||||
|
||||
/// Destroy a timer implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
service_impl_.destroy(impl);
|
||||
}
|
||||
|
||||
/// Cancel any asynchronous wait operations associated with the timer.
|
||||
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.cancel(impl, ec);
|
||||
}
|
||||
|
||||
/// Get the expiry time for the timer as an absolute time.
|
||||
time_type expires_at(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.expires_at(impl);
|
||||
}
|
||||
|
||||
/// Set the expiry time for the timer as an absolute time.
|
||||
std::size_t expires_at(implementation_type& impl,
|
||||
const time_type& expiry_time, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.expires_at(impl, expiry_time, ec);
|
||||
}
|
||||
|
||||
/// Get the expiry time for the timer relative to now.
|
||||
duration_type expires_from_now(const implementation_type& impl) const
|
||||
{
|
||||
return service_impl_.expires_from_now(impl);
|
||||
}
|
||||
|
||||
/// Set the expiry time for the timer relative to now.
|
||||
std::size_t expires_from_now(implementation_type& impl,
|
||||
const duration_type& expiry_time, asio::error_code& ec)
|
||||
{
|
||||
return service_impl_.expires_from_now(impl, expiry_time, ec);
|
||||
}
|
||||
|
||||
// Perform a blocking wait on the timer.
|
||||
void wait(implementation_type& impl, asio::error_code& ec)
|
||||
{
|
||||
service_impl_.wait(impl, ec);
|
||||
}
|
||||
|
||||
// Start an asynchronous wait on the timer.
|
||||
template <typename WaitHandler>
|
||||
void async_wait(implementation_type& impl, WaitHandler handler)
|
||||
{
|
||||
service_impl_.async_wait(impl, handler);
|
||||
}
|
||||
|
||||
private:
|
||||
// The service that provides the platform-specific implementation.
|
||||
service_impl_type& service_impl_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DEADLINE_TIMER_SERVICE_HPP
|
74
libtorrent/include/asio/detail/CVS/Entries
Normal file
|
@ -0,0 +1,74 @@
|
|||
/bind_handler.hpp/1.18/Thu Jan 4 05:44:44 2007//
|
||||
/buffer_resize_guard.hpp/1.9/Thu Jan 4 05:44:44 2007//
|
||||
/buffered_stream_storage.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
||||
/call_stack.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/const_buffers_iterator.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/consuming_buffers.hpp/1.7/Sat Jan 13 13:41:09 2007//
|
||||
/deadline_timer_service.hpp/1.7/Mon Jan 8 02:47:13 2007//
|
||||
/epoll_reactor.hpp/1.40/Thu Jan 4 05:44:44 2007//
|
||||
/epoll_reactor_fwd.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/event.hpp/1.13/Thu Jan 4 05:44:44 2007//
|
||||
/fd_set_adapter.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
||||
/handler_alloc_helpers.hpp/1.8/Thu Jan 4 05:44:44 2007//
|
||||
/handler_invoke_helpers.hpp/1.2/Thu Jan 4 05:44:44 2007//
|
||||
/hash_map.hpp/1.19/Thu Mar 22 21:13:13 2007//
|
||||
/io_control.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
||||
/kqueue_reactor.hpp/1.30/Thu Mar 22 21:08:02 2007//
|
||||
/kqueue_reactor_fwd.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/local_free_on_block_exit.hpp/1.2/Thu Jan 4 05:44:44 2007//
|
||||
/mutex.hpp/1.13/Thu Jan 4 05:44:44 2007//
|
||||
/noncopyable.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/null_event.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/null_mutex.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/null_signal_blocker.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/null_thread.hpp/1.5/Mon Jan 8 22:12:46 2007//
|
||||
/null_tss_ptr.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
||||
/old_win_sdk_compat.hpp/1.5/Sat May 12 08:16:25 2007//
|
||||
/pipe_select_interrupter.hpp/1.11/Thu Jan 4 05:44:44 2007//
|
||||
/pop_options.hpp/1.10/Thu Jan 4 05:44:44 2007//
|
||||
/posix_event.hpp/1.16/Thu Jan 4 05:44:44 2007//
|
||||
/posix_fd_set_adapter.hpp/1.4/Tue Feb 13 07:13:29 2007//
|
||||
/posix_mutex.hpp/1.15/Thu Jan 4 05:44:44 2007//
|
||||
/posix_signal_blocker.hpp/1.10/Sat Feb 17 22:57:37 2007//
|
||||
/posix_thread.hpp/1.17/Thu Jan 4 05:44:45 2007//
|
||||
/posix_tss_ptr.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
||||
/push_options.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
||||
/reactive_socket_service.hpp/1.59/Sun May 13 23:00:01 2007//
|
||||
/reactor_op_queue.hpp/1.24/Thu Jan 4 05:44:45 2007//
|
||||
/resolver_service.hpp/1.11/Thu Jan 4 09:06:56 2007//
|
||||
/scoped_lock.hpp/1.9/Thu Jan 4 05:44:45 2007//
|
||||
/select_interrupter.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
||||
/select_reactor.hpp/1.49/Thu Jan 4 05:44:45 2007//
|
||||
/select_reactor_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/service_base.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/service_id.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/service_registry.hpp/1.19/Tue Feb 13 12:06:43 2007//
|
||||
/service_registry_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/signal_blocker.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
||||
/signal_init.hpp/1.11/Thu Jan 4 05:44:45 2007//
|
||||
/socket_holder.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
||||
/socket_ops.hpp/1.74/Mon May 21 12:34:39 2007//
|
||||
/socket_option.hpp/1.7/Sat Feb 17 22:57:37 2007//
|
||||
/socket_select_interrupter.hpp/1.15/Thu May 10 23:48:52 2007//
|
||||
/socket_types.hpp/1.41/Sun May 13 07:59:21 2007//
|
||||
/strand_service.hpp/1.15/Thu Jan 4 05:44:45 2007//
|
||||
/task_io_service.hpp/1.18/Wed Feb 14 13:26:21 2007//
|
||||
/task_io_service_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/thread.hpp/1.13/Thu Jan 4 05:44:45 2007//
|
||||
/throw_error.hpp/1.3/Thu Jan 4 05:44:45 2007//
|
||||
/timer_queue.hpp/1.6/Sun Apr 22 07:07:15 2007//
|
||||
/timer_queue_base.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
||||
/tss_ptr.hpp/1.8/Thu Jan 4 05:44:45 2007//
|
||||
/win_event.hpp/1.14/Thu Jan 4 05:44:45 2007//
|
||||
/win_fd_set_adapter.hpp/1.4/Thu Jan 4 05:44:45 2007//
|
||||
/win_iocp_io_service.hpp/1.24/Mon Jan 8 01:09:14 2007//
|
||||
/win_iocp_io_service_fwd.hpp/1.4/Thu Jan 4 05:44:45 2007//
|
||||
/win_iocp_operation.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
||||
/win_iocp_socket_service.hpp/1.75/Sat May 12 09:07:32 2007//
|
||||
/win_mutex.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
||||
/win_signal_blocker.hpp/1.9/Thu Jan 4 05:44:45 2007//
|
||||
/win_thread.hpp/1.20/Thu Jan 4 05:44:45 2007//
|
||||
/win_tss_ptr.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
||||
/winsock_init.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
||||
/wrapped_handler.hpp/1.11/Thu Jan 4 05:44:45 2007//
|
||||
D
|
1
libtorrent/include/asio/detail/CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
asio/include/asio/detail
|
1
libtorrent/include/asio/detail/CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
349
libtorrent/include/asio/detail/bind_handler.hpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
//
|
||||
// bind_handler.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_BIND_HANDLER_HPP
|
||||
#define ASIO_DETAIL_BIND_HANDLER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
class binder1
|
||||
{
|
||||
public:
|
||||
binder1(const Handler& handler, const Arg1& arg1)
|
||||
: handler_(handler),
|
||||
arg1_(arg1)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder1<Handler, Arg1>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
inline binder1<Handler, Arg1> bind_handler(const Handler& handler,
|
||||
const Arg1& arg1)
|
||||
{
|
||||
return binder1<Handler, Arg1>(handler, arg1);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
class binder2
|
||||
{
|
||||
public:
|
||||
binder2(const Handler& handler, const Arg1& arg1, const Arg2& arg2)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder2<Handler, Arg1, Arg2>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2>
|
||||
inline binder2<Handler, Arg1, Arg2> bind_handler(const Handler& handler,
|
||||
const Arg1& arg1, const Arg2& arg2)
|
||||
{
|
||||
return binder2<Handler, Arg1, Arg2>(handler, arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
class binder3
|
||||
{
|
||||
public:
|
||||
binder3(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline binder3<Handler, Arg1, Arg2, Arg3> bind_handler(const Handler& handler,
|
||||
const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
|
||||
{
|
||||
return binder3<Handler, Arg1, Arg2, Arg3>(handler, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
class binder4
|
||||
{
|
||||
public:
|
||||
binder4(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4>
|
||||
inline binder4<Handler, Arg1, Arg2, Arg3, Arg4> bind_handler(
|
||||
const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4)
|
||||
{
|
||||
return binder4<Handler, Arg1, Arg2, Arg3, Arg4>(handler, arg1, arg2, arg3,
|
||||
arg4);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
class binder5
|
||||
{
|
||||
public:
|
||||
binder5(const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
: handler_(handler),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4),
|
||||
arg5_(arg5)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
Arg5 arg5_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||
typename Arg4, typename Arg5>
|
||||
inline binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5> bind_handler(
|
||||
const Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
{
|
||||
return binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>(handler, arg1, arg2,
|
||||
arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_BIND_HANDLER_HPP
|
70
libtorrent/include/asio/detail/buffer_resize_guard.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// buffer_resize_guard.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP
|
||||
#define ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <limits>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Helper class to manage buffer resizing in an exception safe way.
|
||||
template <typename Buffer>
|
||||
class buffer_resize_guard
|
||||
{
|
||||
public:
|
||||
// Constructor.
|
||||
buffer_resize_guard(Buffer& buffer)
|
||||
: buffer_(buffer),
|
||||
old_size_(buffer.size())
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor rolls back the buffer resize unless commit was called.
|
||||
~buffer_resize_guard()
|
||||
{
|
||||
if (old_size_
|
||||
!= std::numeric_limits<size_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION())
|
||||
{
|
||||
buffer_.resize(old_size_);
|
||||
}
|
||||
}
|
||||
|
||||
// Commit the resize transaction.
|
||||
void commit()
|
||||
{
|
||||
old_size_
|
||||
= std::numeric_limits<size_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
|
||||
}
|
||||
|
||||
private:
|
||||
// The buffer being managed.
|
||||
Buffer& buffer_;
|
||||
|
||||
// The size of the buffer at the time the guard was constructed.
|
||||
size_t old_size_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP
|
127
libtorrent/include/asio/detail/buffered_stream_storage.hpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// buffered_stream_storage.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP
|
||||
#define ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/config.hpp>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class buffered_stream_storage
|
||||
{
|
||||
public:
|
||||
// The type of the bytes stored in the buffer.
|
||||
typedef unsigned char byte_type;
|
||||
|
||||
// The type used for offsets into the buffer.
|
||||
typedef std::size_t size_type;
|
||||
|
||||
// Constructor.
|
||||
explicit buffered_stream_storage(std::size_t capacity)
|
||||
: begin_offset_(0),
|
||||
end_offset_(0),
|
||||
buffer_(capacity)
|
||||
{
|
||||
}
|
||||
|
||||
/// Clear the buffer.
|
||||
void clear()
|
||||
{
|
||||
begin_offset_ = 0;
|
||||
end_offset_ = 0;
|
||||
}
|
||||
|
||||
// Return a pointer to the beginning of the unread data.
|
||||
byte_type* data()
|
||||
{
|
||||
return &buffer_[0] + begin_offset_;
|
||||
}
|
||||
|
||||
// Return a pointer to the beginning of the unread data.
|
||||
const byte_type* data() const
|
||||
{
|
||||
return &buffer_[0] + begin_offset_;
|
||||
}
|
||||
|
||||
// Is there no unread data in the buffer.
|
||||
bool empty() const
|
||||
{
|
||||
return begin_offset_ == end_offset_;
|
||||
}
|
||||
|
||||
// Return the amount of unread data the is in the buffer.
|
||||
size_type size() const
|
||||
{
|
||||
return end_offset_ - begin_offset_;
|
||||
}
|
||||
|
||||
// Resize the buffer to the specified length.
|
||||
void resize(size_type length)
|
||||
{
|
||||
assert(length <= capacity());
|
||||
if (begin_offset_ + length <= capacity())
|
||||
{
|
||||
end_offset_ = begin_offset_ + length;
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace std; // For memmove.
|
||||
memmove(&buffer_[0], &buffer_[0] + begin_offset_, size());
|
||||
end_offset_ = length;
|
||||
begin_offset_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the maximum size for data in the buffer.
|
||||
size_type capacity() const
|
||||
{
|
||||
return buffer_.size();
|
||||
}
|
||||
|
||||
// Consume multiple bytes from the beginning of the buffer.
|
||||
void consume(size_type count)
|
||||
{
|
||||
assert(begin_offset_ + count <= end_offset_);
|
||||
begin_offset_ += count;
|
||||
if (empty())
|
||||
clear();
|
||||
}
|
||||
|
||||
private:
|
||||
// The offset to the beginning of the unread data.
|
||||
size_type begin_offset_;
|
||||
|
||||
// The offset to the end of the unread data.
|
||||
size_type end_offset_;
|
||||
|
||||
// The data in the buffer.
|
||||
std::vector<byte_type> buffer_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP
|
90
libtorrent/include/asio/detail/call_stack.hpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// call_stack.hpp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_CALL_STACK_HPP
|
||||
#define ASIO_DETAIL_CALL_STACK_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/tss_ptr.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Helper class to determine whether or not the current thread is inside an
|
||||
// invocation of io_service::run() for a specified io_service object.
|
||||
template <typename Owner>
|
||||
class call_stack
|
||||
{
|
||||
public:
|
||||
// Context class automatically pushes an owner on to the stack.
|
||||
class context
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Push the owner on to the stack.
|
||||
explicit context(Owner* d)
|
||||
: owner_(d),
|
||||
next_(call_stack<Owner>::top_)
|
||||
{
|
||||
call_stack<Owner>::top_ = this;
|
||||
}
|
||||
|
||||
// Pop the owner from the stack.
|
||||
~context()
|
||||
{
|
||||
call_stack<Owner>::top_ = next_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class call_stack<Owner>;
|
||||
|
||||
// The owner associated with the context.
|
||||
Owner* owner_;
|
||||
|
||||
// The next element in the stack.
|
||||
context* next_;
|
||||
};
|
||||
|
||||
friend class context;
|
||||
|
||||
// Determine whether the specified owner is on the stack.
|
||||
static bool contains(Owner* d)
|
||||
{
|
||||
context* elem = top_;
|
||||
while (elem)
|
||||
{
|
||||
if (elem->owner_ == d)
|
||||
return true;
|
||||
elem = elem->next_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// The top of the stack of calls for the current thread.
|
||||
static tss_ptr<context> top_;
|
||||
};
|
||||
|
||||
template <typename Owner>
|
||||
tss_ptr<typename call_stack<Owner>::context>
|
||||
call_stack<Owner>::top_;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_CALL_STACK_HPP
|
151
libtorrent/include/asio/detail/const_buffers_iterator.hpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
//
|
||||
// const_buffers_iterator.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
|
||||
#define ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffer.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// A proxy iterator for a sub-range in a list of buffers.
|
||||
template <typename ConstBufferSequence>
|
||||
class const_buffers_iterator
|
||||
: public boost::iterator_facade<const_buffers_iterator<ConstBufferSequence>,
|
||||
const char, boost::bidirectional_traversal_tag>
|
||||
{
|
||||
public:
|
||||
// Default constructor creates an iterator in an undefined state.
|
||||
const_buffers_iterator()
|
||||
{
|
||||
}
|
||||
|
||||
// Create an iterator for the specified position.
|
||||
const_buffers_iterator(const ConstBufferSequence& buffers,
|
||||
std::size_t position)
|
||||
: begin_(buffers.begin()),
|
||||
current_(buffers.begin()),
|
||||
end_(buffers.end()),
|
||||
position_(0)
|
||||
{
|
||||
while (current_ != end_)
|
||||
{
|
||||
current_buffer_ = *current_;
|
||||
std::size_t buffer_size = asio::buffer_size(current_buffer_);
|
||||
if (position - position_ < buffer_size)
|
||||
{
|
||||
current_buffer_position_ = position - position_;
|
||||
position_ = position;
|
||||
return;
|
||||
}
|
||||
position_ += buffer_size;
|
||||
++current_;
|
||||
}
|
||||
current_buffer_ = asio::const_buffer();
|
||||
current_buffer_position_ = 0;
|
||||
}
|
||||
|
||||
std::size_t position() const
|
||||
{
|
||||
return position_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
void increment()
|
||||
{
|
||||
if (current_ == end_)
|
||||
return;
|
||||
|
||||
++position_;
|
||||
|
||||
++current_buffer_position_;
|
||||
if (current_buffer_position_ != asio::buffer_size(current_buffer_))
|
||||
return;
|
||||
|
||||
++current_;
|
||||
current_buffer_position_ = 0;
|
||||
while (current_ != end_)
|
||||
{
|
||||
current_buffer_ = *current_;
|
||||
if (asio::buffer_size(current_buffer_) > 0)
|
||||
return;
|
||||
++current_;
|
||||
}
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
if (position_ == 0)
|
||||
return;
|
||||
|
||||
--position_;
|
||||
|
||||
if (current_buffer_position_ != 0)
|
||||
{
|
||||
--current_buffer_position_;
|
||||
return;
|
||||
}
|
||||
|
||||
typename ConstBufferSequence::const_iterator iter = current_;
|
||||
while (iter != begin_)
|
||||
{
|
||||
--iter;
|
||||
asio::const_buffer buffer = *iter;
|
||||
std::size_t buffer_size = asio::buffer_size(buffer);
|
||||
if (buffer_size > 0)
|
||||
{
|
||||
current_ = iter;
|
||||
current_buffer_ = buffer;
|
||||
current_buffer_position_ = buffer_size - 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool equal(const const_buffers_iterator& other) const
|
||||
{
|
||||
return position_ == other.position_;
|
||||
}
|
||||
|
||||
const char& dereference() const
|
||||
{
|
||||
return asio::buffer_cast<const char*>(
|
||||
current_buffer_)[current_buffer_position_];
|
||||
}
|
||||
|
||||
asio::const_buffer current_buffer_;
|
||||
std::size_t current_buffer_position_;
|
||||
typename ConstBufferSequence::const_iterator begin_;
|
||||
typename ConstBufferSequence::const_iterator current_;
|
||||
typename ConstBufferSequence::const_iterator end_;
|
||||
std::size_t position_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
|
205
libtorrent/include/asio/detail/consuming_buffers.hpp
Normal file
|
@ -0,0 +1,205 @@
|
|||
//
|
||||
// consuming_buffers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_CONSUMING_BUFFERS_HPP
|
||||
#define ASIO_DETAIL_CONSUMING_BUFFERS_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// A proxy iterator for a sub-range in a list of buffers.
|
||||
template <typename Buffer, typename Buffer_Iterator>
|
||||
class consuming_buffers_iterator
|
||||
: public boost::iterator_facade<
|
||||
consuming_buffers_iterator<Buffer, Buffer_Iterator>,
|
||||
const Buffer, boost::forward_traversal_tag>
|
||||
{
|
||||
public:
|
||||
// Default constructor creates an end iterator.
|
||||
consuming_buffers_iterator()
|
||||
: at_end_(true)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct with a buffer for the first entry and an iterator
|
||||
// range for the remaining entries.
|
||||
consuming_buffers_iterator(bool at_end, const Buffer& first,
|
||||
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder)
|
||||
: at_end_(at_end),
|
||||
first_(buffer(first, max_size)),
|
||||
begin_remainder_(begin_remainder),
|
||||
end_remainder_(end_remainder),
|
||||
offset_(0)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
enum { max_size = 65536 };
|
||||
|
||||
void increment()
|
||||
{
|
||||
if (!at_end_)
|
||||
{
|
||||
if (begin_remainder_ == end_remainder_
|
||||
|| offset_ + buffer_size(first_) >= max_size)
|
||||
{
|
||||
at_end_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset_ += buffer_size(first_);
|
||||
first_ = buffer(*begin_remainder_++, max_size - offset_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool equal(const consuming_buffers_iterator& other) const
|
||||
{
|
||||
if (at_end_ && other.at_end_)
|
||||
return true;
|
||||
return !at_end_ && !other.at_end_
|
||||
&& buffer_cast<const void*>(first_)
|
||||
== buffer_cast<const void*>(other.first_)
|
||||
&& buffer_size(first_) == buffer_size(other.first_)
|
||||
&& begin_remainder_ == other.begin_remainder_
|
||||
&& end_remainder_ == other.end_remainder_;
|
||||
}
|
||||
|
||||
const Buffer& dereference() const
|
||||
{
|
||||
return first_;
|
||||
}
|
||||
|
||||
bool at_end_;
|
||||
Buffer first_;
|
||||
Buffer_Iterator begin_remainder_;
|
||||
Buffer_Iterator end_remainder_;
|
||||
std::size_t offset_;
|
||||
};
|
||||
|
||||
// A proxy for a sub-range in a list of buffers.
|
||||
template <typename Buffer, typename Buffers>
|
||||
class consuming_buffers
|
||||
{
|
||||
public:
|
||||
// The type for each element in the list of buffers.
|
||||
typedef Buffer value_type;
|
||||
|
||||
// A forward-only iterator type that may be used to read elements.
|
||||
typedef consuming_buffers_iterator<Buffer, typename Buffers::const_iterator>
|
||||
const_iterator;
|
||||
|
||||
// Construct to represent the entire list of buffers.
|
||||
consuming_buffers(const Buffers& buffers)
|
||||
: buffers_(buffers),
|
||||
at_end_(buffers_.begin() == buffers_.end()),
|
||||
first_(*buffers_.begin()),
|
||||
begin_remainder_(buffers_.begin())
|
||||
{
|
||||
if (!at_end_)
|
||||
++begin_remainder_;
|
||||
}
|
||||
|
||||
// Copy constructor.
|
||||
consuming_buffers(const consuming_buffers& other)
|
||||
: buffers_(other.buffers_),
|
||||
at_end_(other.at_end_),
|
||||
first_(other.first_),
|
||||
begin_remainder_(buffers_.begin())
|
||||
{
|
||||
typename Buffers::const_iterator first = other.buffers_.begin();
|
||||
typename Buffers::const_iterator second = other.begin_remainder_;
|
||||
std::advance(begin_remainder_, std::distance(first, second));
|
||||
}
|
||||
|
||||
// Assignment operator.
|
||||
consuming_buffers& operator=(const consuming_buffers& other)
|
||||
{
|
||||
buffers_ = other.buffers_;
|
||||
at_end_ = other.at_end_;
|
||||
first_ = other.first_;
|
||||
begin_remainder_ = buffers_.begin();
|
||||
typename Buffers::const_iterator first = other.buffers_.begin();
|
||||
typename Buffers::const_iterator second = other.begin_remainder_;
|
||||
std::advance(begin_remainder_, std::distance(first, second));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Get a forward-only iterator to the first element.
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(at_end_, first_, begin_remainder_, buffers_.end());
|
||||
}
|
||||
|
||||
// Get a forward-only iterator for one past the last element.
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
// Consume the specified number of bytes from the buffers.
|
||||
void consume(std::size_t size)
|
||||
{
|
||||
// Remove buffers from the start until the specified size is reached.
|
||||
while (size > 0 && !at_end_)
|
||||
{
|
||||
if (buffer_size(first_) <= size)
|
||||
{
|
||||
size -= buffer_size(first_);
|
||||
if (begin_remainder_ == buffers_.end())
|
||||
at_end_ = true;
|
||||
else
|
||||
first_ = *begin_remainder_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_ = first_ + size;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any more empty buffers at the start.
|
||||
while (!at_end_ && buffer_size(first_) == 0)
|
||||
{
|
||||
if (begin_remainder_ == buffers_.end())
|
||||
at_end_ = true;
|
||||
else
|
||||
first_ = *begin_remainder_++;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Buffers buffers_;
|
||||
bool at_end_;
|
||||
Buffer first_;
|
||||
typename Buffers::const_iterator begin_remainder_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP
|
199
libtorrent/include/asio/detail/deadline_timer_service.hpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
//
|
||||
// deadline_timer_service.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
|
||||
#define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
#include "asio/detail/socket_ops.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
#include "asio/detail/timer_queue.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename Time_Traits, typename Timer_Scheduler>
|
||||
class deadline_timer_service
|
||||
: public asio::detail::service_base<
|
||||
deadline_timer_service<Time_Traits, Timer_Scheduler> >
|
||||
{
|
||||
public:
|
||||
// The time type.
|
||||
typedef typename Time_Traits::time_type time_type;
|
||||
|
||||
// The duration type.
|
||||
typedef typename Time_Traits::duration_type duration_type;
|
||||
|
||||
// The implementation type of the timer. This type is dependent on the
|
||||
// underlying implementation of the timer service.
|
||||
struct implementation_type
|
||||
: private asio::detail::noncopyable
|
||||
{
|
||||
time_type expiry;
|
||||
bool might_have_pending_waits;
|
||||
};
|
||||
|
||||
// Constructor.
|
||||
deadline_timer_service(asio::io_service& io_service)
|
||||
: asio::detail::service_base<
|
||||
deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
|
||||
scheduler_(asio::use_service<Timer_Scheduler>(io_service))
|
||||
{
|
||||
scheduler_.add_timer_queue(timer_queue_);
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~deadline_timer_service()
|
||||
{
|
||||
scheduler_.remove_timer_queue(timer_queue_);
|
||||
}
|
||||
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
}
|
||||
|
||||
// Construct a new timer implementation.
|
||||
void construct(implementation_type& impl)
|
||||
{
|
||||
impl.expiry = time_type();
|
||||
impl.might_have_pending_waits = false;
|
||||
}
|
||||
|
||||
// Destroy a timer implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
asio::error_code ec;
|
||||
cancel(impl, ec);
|
||||
}
|
||||
|
||||
// Cancel any asynchronous wait operations associated with the timer.
|
||||
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
|
||||
{
|
||||
if (!impl.might_have_pending_waits)
|
||||
{
|
||||
ec = asio::error_code();
|
||||
return 0;
|
||||
}
|
||||
std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
|
||||
impl.might_have_pending_waits = false;
|
||||
ec = asio::error_code();
|
||||
return count;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer as an absolute time.
|
||||
time_type expires_at(const implementation_type& impl) const
|
||||
{
|
||||
return impl.expiry;
|
||||
}
|
||||
|
||||
// Set the expiry time for the timer as an absolute time.
|
||||
std::size_t expires_at(implementation_type& impl,
|
||||
const time_type& expiry_time, asio::error_code& ec)
|
||||
{
|
||||
std::size_t count = cancel(impl, ec);
|
||||
impl.expiry = expiry_time;
|
||||
ec = asio::error_code();
|
||||
return count;
|
||||
}
|
||||
|
||||
// Get the expiry time for the timer relative to now.
|
||||
duration_type expires_from_now(const implementation_type& impl) const
|
||||
{
|
||||
return Time_Traits::subtract(expires_at(impl), Time_Traits::now());
|
||||
}
|
||||
|
||||
// Set the expiry time for the timer relative to now.
|
||||
std::size_t expires_from_now(implementation_type& impl,
|
||||
const duration_type& expiry_time, asio::error_code& ec)
|
||||
{
|
||||
return expires_at(impl,
|
||||
Time_Traits::add(Time_Traits::now(), expiry_time), ec);
|
||||
}
|
||||
|
||||
// Perform a blocking wait on the timer.
|
||||
void wait(implementation_type& impl, asio::error_code& ec)
|
||||
{
|
||||
time_type now = Time_Traits::now();
|
||||
while (Time_Traits::less_than(now, impl.expiry))
|
||||
{
|
||||
boost::posix_time::time_duration timeout =
|
||||
Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now));
|
||||
::timeval tv;
|
||||
tv.tv_sec = timeout.total_seconds();
|
||||
tv.tv_usec = timeout.total_microseconds() % 1000000;
|
||||
asio::error_code ec;
|
||||
socket_ops::select(0, 0, 0, 0, &tv, ec);
|
||||
now = Time_Traits::now();
|
||||
}
|
||||
ec = asio::error_code();
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
class wait_handler
|
||||
{
|
||||
public:
|
||||
wait_handler(asio::io_service& io_service, Handler handler)
|
||||
: io_service_(io_service),
|
||||
work_(io_service),
|
||||
handler_(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const asio::error_code& result)
|
||||
{
|
||||
io_service_.post(detail::bind_handler(handler_, result));
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_service& io_service_;
|
||||
asio::io_service::work work_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
// Start an asynchronous wait on the timer.
|
||||
template <typename Handler>
|
||||
void async_wait(implementation_type& impl, Handler handler)
|
||||
{
|
||||
impl.might_have_pending_waits = true;
|
||||
scheduler_.schedule_timer(timer_queue_, impl.expiry,
|
||||
wait_handler<Handler>(this->io_service(), handler), &impl);
|
||||
}
|
||||
|
||||
private:
|
||||
// The queue of timers.
|
||||
timer_queue<Time_Traits> timer_queue_;
|
||||
|
||||
// The object that schedules and executes timers. Usually a reactor.
|
||||
Timer_Scheduler& scheduler_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
|
613
libtorrent/include/asio/detail/epoll_reactor.hpp
Normal file
|
@ -0,0 +1,613 @@
|
|||
//
|
||||
// epoll_reactor.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_EPOLL_REACTOR_HPP
|
||||
#define ASIO_DETAIL_EPOLL_REACTOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/epoll_reactor_fwd.hpp"
|
||||
|
||||
#if defined(ASIO_HAS_EPOLL)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <sys/epoll.h>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/io_service.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/hash_map.hpp"
|
||||
#include "asio/detail/mutex.hpp"
|
||||
#include "asio/detail/task_io_service.hpp"
|
||||
#include "asio/detail/thread.hpp"
|
||||
#include "asio/detail/reactor_op_queue.hpp"
|
||||
#include "asio/detail/select_interrupter.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
#include "asio/detail/signal_blocker.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
#include "asio/detail/timer_queue.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <bool Own_Thread>
|
||||
class epoll_reactor
|
||||
: public asio::detail::service_base<epoll_reactor<Own_Thread> >
|
||||
{
|
||||
public:
|
||||
// Constructor.
|
||||
epoll_reactor(asio::io_service& io_service)
|
||||
: asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
|
||||
mutex_(),
|
||||
epoll_fd_(do_epoll_create()),
|
||||
wait_in_progress_(false),
|
||||
interrupter_(),
|
||||
read_op_queue_(),
|
||||
write_op_queue_(),
|
||||
except_op_queue_(),
|
||||
pending_cancellations_(),
|
||||
stop_thread_(false),
|
||||
thread_(0),
|
||||
shutdown_(false)
|
||||
{
|
||||
// Start the reactor's internal thread only if needed.
|
||||
if (Own_Thread)
|
||||
{
|
||||
asio::detail::signal_blocker sb;
|
||||
thread_ = new asio::detail::thread(
|
||||
bind_handler(&epoll_reactor::call_run_thread, this));
|
||||
}
|
||||
|
||||
// Add the interrupter's descriptor to epoll.
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLIN | EPOLLERR;
|
||||
ev.data.fd = interrupter_.read_descriptor();
|
||||
epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~epoll_reactor()
|
||||
{
|
||||
shutdown_service();
|
||||
close(epoll_fd_);
|
||||
}
|
||||
|
||||
// Destroy all user-defined handler objects owned by the service.
|
||||
void shutdown_service()
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
shutdown_ = true;
|
||||
stop_thread_ = true;
|
||||
lock.unlock();
|
||||
|
||||
if (thread_)
|
||||
{
|
||||
interrupter_.interrupt();
|
||||
thread_->join();
|
||||
delete thread_;
|
||||
thread_ = 0;
|
||||
}
|
||||
|
||||
read_op_queue_.destroy_operations();
|
||||
write_op_queue_.destroy_operations();
|
||||
except_op_queue_.destroy_operations();
|
||||
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->destroy_timers();
|
||||
timer_queues_.clear();
|
||||
}
|
||||
|
||||
// Register a socket with the reactor. Returns 0 on success, system error
|
||||
// code on failure.
|
||||
int register_descriptor(socket_type descriptor)
|
||||
{
|
||||
// No need to lock according to epoll documentation.
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = 0;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
return errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Start a new read operation. The handler object will be invoked when the
|
||||
// given descriptor is ready to be read, or an error has occurred.
|
||||
template <typename Handler>
|
||||
void start_read_op(socket_type descriptor, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (shutdown_)
|
||||
return;
|
||||
|
||||
if (!read_op_queue_.has_operation(descriptor))
|
||||
if (handler(asio::error_code()))
|
||||
return;
|
||||
|
||||
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
|
||||
if (write_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLOUT;
|
||||
if (except_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new write operation. The handler object will be invoked when the
|
||||
// given descriptor is ready to be written, or an error has occurred.
|
||||
template <typename Handler>
|
||||
void start_write_op(socket_type descriptor, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (shutdown_)
|
||||
return;
|
||||
|
||||
if (!write_op_queue_.has_operation(descriptor))
|
||||
if (handler(asio::error_code()))
|
||||
return;
|
||||
|
||||
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLIN;
|
||||
if (except_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new exception operation. The handler object will be invoked when
|
||||
// the given descriptor has exception information, or an error has occurred.
|
||||
template <typename Handler>
|
||||
void start_except_op(socket_type descriptor, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (shutdown_)
|
||||
return;
|
||||
|
||||
if (except_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLPRI | EPOLLERR | EPOLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLIN;
|
||||
if (write_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLOUT;
|
||||
ev.data.fd = descriptor;
|
||||
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start new write and exception operations. The handler object will be
|
||||
// invoked when the given descriptor is ready for writing or has exception
|
||||
// information available, or an error has occurred.
|
||||
template <typename Handler>
|
||||
void start_write_and_except_ops(socket_type descriptor, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
if (shutdown_)
|
||||
return;
|
||||
|
||||
bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler);
|
||||
need_mod = except_op_queue_.enqueue_operation(descriptor, handler)
|
||||
&& need_mod;
|
||||
if (need_mod)
|
||||
{
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= EPOLLIN;
|
||||
ev.data.fd = descriptor;
|
||||
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel all operations associated with the given descriptor. The
|
||||
// handlers associated with the descriptor will be invoked with the
|
||||
// operation_aborted error.
|
||||
void cancel_ops(socket_type descriptor)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
cancel_ops_unlocked(descriptor);
|
||||
}
|
||||
|
||||
// Enqueue cancellation of all operations associated with the given
|
||||
// descriptor. The handlers associated with the descriptor will be invoked
|
||||
// with the operation_aborted error. This function does not acquire the
|
||||
// epoll_reactor's mutex, and so should only be used from within a reactor
|
||||
// handler.
|
||||
void enqueue_cancel_ops_unlocked(socket_type descriptor)
|
||||
{
|
||||
pending_cancellations_.push_back(descriptor);
|
||||
}
|
||||
|
||||
// Cancel any operations that are running against the descriptor and remove
|
||||
// its registration from the reactor.
|
||||
void close_descriptor(socket_type descriptor)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
// Remove the descriptor from epoll.
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
|
||||
|
||||
// Cancel any outstanding operations associated with the descriptor.
|
||||
cancel_ops_unlocked(descriptor);
|
||||
}
|
||||
|
||||
// Add a new timer queue to the reactor.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
timer_queues_.push_back(&timer_queue);
|
||||
}
|
||||
|
||||
// Remove a timer queue from the reactor.
|
||||
template <typename Time_Traits>
|
||||
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
if (timer_queues_[i] == &timer_queue)
|
||||
{
|
||||
timer_queues_.erase(timer_queues_.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule a timer in the given timer queue to expire at the specified
|
||||
// absolute time. The handler object will be invoked when the timer expires.
|
||||
template <typename Time_Traits, typename Handler>
|
||||
void schedule_timer(timer_queue<Time_Traits>& timer_queue,
|
||||
const typename Time_Traits::time_type& time, Handler handler, void* token)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
if (!shutdown_)
|
||||
if (timer_queue.enqueue_timer(time, handler, token))
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Cancel the timer associated with the given token. Returns the number of
|
||||
// handlers that have been posted or dispatched.
|
||||
template <typename Time_Traits>
|
||||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
return timer_queue.cancel_timer(token);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class task_io_service<epoll_reactor<Own_Thread> >;
|
||||
|
||||
// Run epoll once until interrupted or events are ready to be dispatched.
|
||||
void run(bool block)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
// Dispatch any operation cancellations that were made while the select
|
||||
// loop was not running.
|
||||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
// We can return immediately if there's no work to do and the reactor is
|
||||
// not supposed to block.
|
||||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
int timeout = block ? get_timeout() : 0;
|
||||
wait_in_progress_ = true;
|
||||
lock.unlock();
|
||||
|
||||
// Block on the epoll descriptor.
|
||||
epoll_event events[128];
|
||||
int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
|
||||
|
||||
lock.lock();
|
||||
wait_in_progress_ = false;
|
||||
|
||||
// Block signals while dispatching operations.
|
||||
asio::detail::signal_blocker sb;
|
||||
|
||||
// Dispatch the waiting events.
|
||||
for (int i = 0; i < num_events; ++i)
|
||||
{
|
||||
int descriptor = events[i].data.fd;
|
||||
if (descriptor == interrupter_.read_descriptor())
|
||||
{
|
||||
interrupter_.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
||||
{
|
||||
asio::error_code ec;
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = 0;
|
||||
ev.data.fd = descriptor;
|
||||
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool more_reads = false;
|
||||
bool more_writes = false;
|
||||
bool more_except = false;
|
||||
asio::error_code ec;
|
||||
|
||||
// Exception operations must be processed first to ensure that any
|
||||
// out-of-band data is read before normal data.
|
||||
if (events[i].events & EPOLLPRI)
|
||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_except = except_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLIN)
|
||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_reads = read_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLOUT)
|
||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_writes = write_op_queue_.has_operation(descriptor);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLERR | EPOLLHUP;
|
||||
if (more_reads)
|
||||
ev.events |= EPOLLIN;
|
||||
if (more_writes)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (more_except)
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
ec = asio::error_code(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
void run_thread()
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
while (!stop_thread_)
|
||||
{
|
||||
lock.unlock();
|
||||
run(true);
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
|
||||
// Entry point for the select loop thread.
|
||||
static void call_run_thread(epoll_reactor* reactor)
|
||||
{
|
||||
reactor->run_thread();
|
||||
}
|
||||
|
||||
// Interrupt the select loop.
|
||||
void interrupt()
|
||||
{
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// The hint to pass to epoll_create to size its data structures.
|
||||
enum { epoll_size = 20000 };
|
||||
|
||||
// Create the epoll file descriptor. Throws an exception if the descriptor
|
||||
// cannot be created.
|
||||
static int do_epoll_create()
|
||||
{
|
||||
int fd = epoll_create(epoll_size);
|
||||
if (fd == -1)
|
||||
{
|
||||
boost::throw_exception(asio::system_error(
|
||||
asio::error_code(errno, asio::native_ecat),
|
||||
"epoll"));
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Check if all timer queues are empty.
|
||||
bool all_timer_queues_are_empty() const
|
||||
{
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
if (!timer_queues_[i]->empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the timeout value for the epoll_wait call. The timeout value is
|
||||
// returned as a number of milliseconds. A return value of -1 indicates
|
||||
// that epoll_wait should block indefinitely.
|
||||
int get_timeout()
|
||||
{
|
||||
if (all_timer_queues_are_empty())
|
||||
return -1;
|
||||
|
||||
// By default we will wait no longer than 5 minutes. This will ensure that
|
||||
// any changes to the system clock are detected after no longer than this.
|
||||
boost::posix_time::time_duration minimum_wait_duration
|
||||
= boost::posix_time::minutes(5);
|
||||
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
boost::posix_time::time_duration wait_duration
|
||||
= timer_queues_[i]->wait_duration();
|
||||
if (wait_duration < minimum_wait_duration)
|
||||
minimum_wait_duration = wait_duration;
|
||||
}
|
||||
|
||||
if (minimum_wait_duration > boost::posix_time::time_duration())
|
||||
{
|
||||
return minimum_wait_duration.total_milliseconds();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel all operations associated with the given descriptor. The do_cancel
|
||||
// function of the handler objects will be invoked. This function does not
|
||||
// acquire the epoll_reactor's mutex.
|
||||
void cancel_ops_unlocked(socket_type descriptor)
|
||||
{
|
||||
bool interrupt = read_op_queue_.cancel_operations(descriptor);
|
||||
interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
|
||||
interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
|
||||
if (interrupt)
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
// The epoll file descriptor.
|
||||
int epoll_fd_;
|
||||
|
||||
// Whether the epoll_wait call is currently in progress
|
||||
bool wait_in_progress_;
|
||||
|
||||
// The interrupter is used to break a blocking epoll_wait call.
|
||||
select_interrupter interrupter_;
|
||||
|
||||
// The queue of read operations.
|
||||
reactor_op_queue<socket_type> read_op_queue_;
|
||||
|
||||
// The queue of write operations.
|
||||
reactor_op_queue<socket_type> write_op_queue_;
|
||||
|
||||
// The queue of except operations.
|
||||
reactor_op_queue<socket_type> except_op_queue_;
|
||||
|
||||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
// Does the reactor loop thread need to stop.
|
||||
bool stop_thread_;
|
||||
|
||||
// The thread that is running the reactor loop.
|
||||
asio::detail::thread* thread_;
|
||||
|
||||
// Whether the service has been shut down.
|
||||
bool shutdown_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#endif // defined(ASIO_HAS_EPOLL)
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_EPOLL_REACTOR_HPP
|
47
libtorrent/include/asio/detail/epoll_reactor_fwd.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// epoll_reactor_fwd.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP
|
||||
#define ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#if !defined(ASIO_DISABLE_EPOLL)
|
||||
#if defined(__linux__) // This service is only supported on Linux.
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <linux/version.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45.
|
||||
|
||||
// Define this to indicate that epoll is supported on the target platform.
|
||||
#define ASIO_HAS_EPOLL 1
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <bool Own_Thread>
|
||||
class epoll_reactor;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45)
|
||||
#endif // defined(__linux__)
|
||||
#endif // !defined(ASIO_DISABLE_EPOLL)
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP
|
50
libtorrent/include/asio/detail/event.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// event.hpp
|
||||
// ~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_EVENT_HPP
|
||||
#define ASIO_DETAIL_EVENT_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS)
|
||||
# include "asio/detail/null_event.hpp"
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
# include "asio/detail/win_event.hpp"
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include "asio/detail/posix_event.hpp"
|
||||
#else
|
||||
# error Only Windows and POSIX are supported!
|
||||
#endif
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS)
|
||||
typedef null_event event;
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
typedef win_event event;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
typedef posix_event event;
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_EVENT_HPP
|
41
libtorrent/include/asio/detail/fd_set_adapter.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// fd_set_adapter.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_FD_SET_ADAPTER_HPP
|
||||
#define ASIO_DETAIL_FD_SET_ADAPTER_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/posix_fd_set_adapter.hpp"
|
||||
#include "asio/detail/win_fd_set_adapter.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
typedef win_fd_set_adapter fd_set_adapter;
|
||||
#else
|
||||
typedef posix_fd_set_adapter fd_set_adapter;
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_FD_SET_ADAPTER_HPP
|
256
libtorrent/include/asio/detail/handler_alloc_helpers.hpp
Normal file
|
@ -0,0 +1,256 @@
|
|||
//
|
||||
// handler_alloc_helpers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
|
||||
#define ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/handler_alloc_hook.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
// Calls to asio_handler_allocate and asio_handler_deallocate must be made from
|
||||
// a namespace that does not contain any overloads of these functions. The
|
||||
// asio_handler_alloc_helpers namespace is defined here for that purpose.
|
||||
namespace asio_handler_alloc_helpers {
|
||||
|
||||
template <typename Handler>
|
||||
inline void* allocate(std::size_t s, Handler* h)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
return ::operator new(s);
|
||||
#else
|
||||
using namespace asio;
|
||||
return asio_handler_allocate(s, h);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
inline void deallocate(void* p, std::size_t s, Handler* h)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
::operator delete(p);
|
||||
#else
|
||||
using namespace asio;
|
||||
asio_handler_deallocate(p, s, h);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace asio_handler_alloc_helpers
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
// Traits for handler allocation.
|
||||
template <typename Handler, typename Object>
|
||||
struct handler_alloc_traits
|
||||
{
|
||||
typedef Handler handler_type;
|
||||
typedef Object value_type;
|
||||
typedef Object* pointer_type;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object));
|
||||
};
|
||||
|
||||
template <typename Alloc_Traits>
|
||||
class handler_ptr;
|
||||
|
||||
// Helper class to provide RAII on uninitialised handler memory.
|
||||
template <typename Alloc_Traits>
|
||||
class raw_handler_ptr
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
typedef typename Alloc_Traits::handler_type handler_type;
|
||||
typedef typename Alloc_Traits::value_type value_type;
|
||||
typedef typename Alloc_Traits::pointer_type pointer_type;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
|
||||
|
||||
// Constructor allocates the memory.
|
||||
raw_handler_ptr(handler_type& handler)
|
||||
: handler_(handler),
|
||||
pointer_(static_cast<pointer_type>(
|
||||
asio_handler_alloc_helpers::allocate(value_size, &handler_)))
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor automatically deallocates memory, unless it has been stolen by
|
||||
// a handler_ptr object.
|
||||
~raw_handler_ptr()
|
||||
{
|
||||
if (pointer_)
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer_, value_size, &handler_);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class handler_ptr<Alloc_Traits>;
|
||||
handler_type& handler_;
|
||||
pointer_type pointer_;
|
||||
};
|
||||
|
||||
// Helper class to provide RAII on uninitialised handler memory.
|
||||
template <typename Alloc_Traits>
|
||||
class handler_ptr
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
typedef typename Alloc_Traits::handler_type handler_type;
|
||||
typedef typename Alloc_Traits::value_type value_type;
|
||||
typedef typename Alloc_Traits::pointer_type pointer_type;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
|
||||
typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type;
|
||||
|
||||
// Take ownership of existing memory.
|
||||
handler_ptr(handler_type& handler, pointer_type pointer)
|
||||
: handler_(handler),
|
||||
pointer_(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
handler_ptr(raw_ptr_type& raw_ptr)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type)
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
|
||||
Arg5& a5)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5, typename Arg6>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
|
||||
Arg5& a5, Arg6& a6)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5, typename Arg6, typename Arg7>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
|
||||
Arg5& a5, Arg6& a6, Arg7& a7)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Construct object in raw memory and take ownership if construction succeeds.
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
|
||||
typename Arg5, typename Arg6, typename Arg7, typename Arg8>
|
||||
handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
|
||||
Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8)
|
||||
: handler_(raw_ptr.handler_),
|
||||
pointer_(new (raw_ptr.pointer_) value_type(
|
||||
a1, a2, a3, a4, a5, a6, a7, a8))
|
||||
{
|
||||
raw_ptr.pointer_ = 0;
|
||||
}
|
||||
|
||||
// Destructor automatically deallocates memory, unless it has been released.
|
||||
~handler_ptr()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// Get the memory.
|
||||
pointer_type get() const
|
||||
{
|
||||
return pointer_;
|
||||
}
|
||||
|
||||
// Release ownership of the memory.
|
||||
pointer_type release()
|
||||
{
|
||||
pointer_type tmp = pointer_;
|
||||
pointer_ = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Explicitly destroy and deallocate the memory.
|
||||
void reset()
|
||||
{
|
||||
if (pointer_)
|
||||
{
|
||||
pointer_->value_type::~value_type();
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer_, value_size, &handler_);
|
||||
pointer_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
handler_type& handler_;
|
||||
pointer_type pointer_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
|
47
libtorrent/include/asio/detail/handler_invoke_helpers.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// handler_invoke_helpers.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
|
||||
#define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/handler_invoke_hook.hpp"
|
||||
|
||||
// Calls to asio_handler_invoke must be made from a namespace that does not
|
||||
// contain overloads of this function. The asio_handler_invoke_helpers
|
||||
// namespace is defined here for that purpose.
|
||||
namespace asio_handler_invoke_helpers {
|
||||
|
||||
template <typename Function, typename Context>
|
||||
inline void invoke(const Function& function, Context* context)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
Function tmp(function);
|
||||
tmp();
|
||||
#else
|
||||
using namespace asio;
|
||||
asio_handler_invoke(function, context);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace asio_handler_invoke_helpers
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
|
209
libtorrent/include/asio/detail/hash_map.hpp
Normal file
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// hash_map.hpp
|
||||
// ~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_HASH_MAP_HPP
|
||||
#define ASIO_DETAIL_HASH_MAP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
inline std::size_t calculate_hash_value(const T& t)
|
||||
{
|
||||
return boost::hash_value(t);
|
||||
}
|
||||
|
||||
#if defined(_WIN64)
|
||||
inline std::size_t calculate_hash_value(SOCKET s)
|
||||
{
|
||||
return static_cast<std::size_t>(s);
|
||||
}
|
||||
#endif // defined(_WIN64)
|
||||
|
||||
template <typename K, typename V>
|
||||
class hash_map
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// The type of a value in the map.
|
||||
typedef std::pair<K, V> value_type;
|
||||
|
||||
// The type of a non-const iterator over the hash map.
|
||||
typedef typename std::list<value_type>::iterator iterator;
|
||||
|
||||
// The type of a const iterator over the hash map.
|
||||
typedef typename std::list<value_type>::const_iterator const_iterator;
|
||||
|
||||
// Constructor.
|
||||
hash_map()
|
||||
{
|
||||
// Initialise all buckets to empty.
|
||||
for (size_t i = 0; i < num_buckets; ++i)
|
||||
buckets_[i].first = buckets_[i].last = values_.end();
|
||||
}
|
||||
|
||||
// Get an iterator for the beginning of the map.
|
||||
iterator begin()
|
||||
{
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
// Get an iterator for the beginning of the map.
|
||||
const_iterator begin() const
|
||||
{
|
||||
return values_.begin();
|
||||
}
|
||||
|
||||
// Get an iterator for the end of the map.
|
||||
iterator end()
|
||||
{
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
// Get an iterator for the end of the map.
|
||||
const_iterator end() const
|
||||
{
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
// Check whether the map is empty.
|
||||
bool empty() const
|
||||
{
|
||||
return values_.empty();
|
||||
}
|
||||
|
||||
// Find an entry in the map.
|
||||
iterator find(const K& k)
|
||||
{
|
||||
size_t bucket = calculate_hash_value(k) % num_buckets;
|
||||
iterator it = buckets_[bucket].first;
|
||||
if (it == values_.end())
|
||||
return values_.end();
|
||||
iterator end = buckets_[bucket].last;
|
||||
++end;
|
||||
while (it != end)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
++it;
|
||||
}
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
// Find an entry in the map.
|
||||
const_iterator find(const K& k) const
|
||||
{
|
||||
size_t bucket = calculate_hash_value(k) % num_buckets;
|
||||
const_iterator it = buckets_[bucket].first;
|
||||
if (it == values_.end())
|
||||
return it;
|
||||
const_iterator end = buckets_[bucket].last;
|
||||
++end;
|
||||
while (it != end)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
++it;
|
||||
}
|
||||
return values_.end();
|
||||
}
|
||||
|
||||
// Insert a new entry into the map.
|
||||
std::pair<iterator, bool> insert(const value_type& v)
|
||||
{
|
||||
size_t bucket = calculate_hash_value(v.first) % num_buckets;
|
||||
iterator it = buckets_[bucket].first;
|
||||
if (it == values_.end())
|
||||
{
|
||||
buckets_[bucket].first = buckets_[bucket].last =
|
||||
values_.insert(values_.end(), v);
|
||||
return std::pair<iterator, bool>(buckets_[bucket].last, true);
|
||||
}
|
||||
iterator end = buckets_[bucket].last;
|
||||
++end;
|
||||
while (it != end)
|
||||
{
|
||||
if (it->first == v.first)
|
||||
return std::pair<iterator, bool>(it, false);
|
||||
++it;
|
||||
}
|
||||
buckets_[bucket].last = values_.insert(end, v);
|
||||
return std::pair<iterator, bool>(buckets_[bucket].last, true);
|
||||
}
|
||||
|
||||
// Erase an entry from the map.
|
||||
void erase(iterator it)
|
||||
{
|
||||
assert(it != values_.end());
|
||||
|
||||
size_t bucket = calculate_hash_value(it->first) % num_buckets;
|
||||
bool is_first = (it == buckets_[bucket].first);
|
||||
bool is_last = (it == buckets_[bucket].last);
|
||||
if (is_first && is_last)
|
||||
buckets_[bucket].first = buckets_[bucket].last = values_.end();
|
||||
else if (is_first)
|
||||
++buckets_[bucket].first;
|
||||
else if (is_last)
|
||||
--buckets_[bucket].last;
|
||||
|
||||
values_.erase(it);
|
||||
}
|
||||
|
||||
// Remove all entries from the map.
|
||||
void clear()
|
||||
{
|
||||
// Clear the values.
|
||||
values_.clear();
|
||||
|
||||
// Initialise all buckets to empty.
|
||||
for (size_t i = 0; i < num_buckets; ++i)
|
||||
buckets_[i].first = buckets_[i].last = values_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
// The list of all values in the hash map.
|
||||
std::list<value_type> values_;
|
||||
|
||||
// The type for a bucket in the hash table.
|
||||
struct bucket_type
|
||||
{
|
||||
iterator first;
|
||||
iterator last;
|
||||
};
|
||||
|
||||
// The number of buckets in the hash.
|
||||
enum { num_buckets = 1021 };
|
||||
|
||||
// The buckets in the hash.
|
||||
bucket_type buckets_[num_buckets];
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_HASH_MAP_HPP
|
137
libtorrent/include/asio/detail/io_control.hpp
Normal file
|
@ -0,0 +1,137 @@
|
|||
//
|
||||
// io_control.hpp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef ASIO_DETAIL_IO_CONTROL_HPP
|
||||
#define ASIO_DETAIL_IO_CONTROL_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <cstddef>
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
namespace io_control {
|
||||
|
||||
// IO control command for non-blocking I/O.
|
||||
class non_blocking_io
|
||||
{
|
||||
public:
|
||||
// Default constructor.
|
||||
non_blocking_io()
|
||||
: value_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct with a specific command value.
|
||||
non_blocking_io(bool value)
|
||||
: value_(value ? 1 : 0)
|
||||
{
|
||||
}
|
||||
|
||||
// Get the name of the IO control command.
|
||||
int name() const
|
||||
{
|
||||
return FIONBIO;
|
||||
}
|
||||
|
||||
// Set the value of the I/O control command.
|
||||
void set(bool value)
|
||||
{
|
||||
value_ = value ? 1 : 0;
|
||||
}
|
||||
|
||||
// Get the current value of the I/O control command.
|
||||
bool get() const
|
||||
{
|
||||
return value_ != 0;
|
||||
}
|
||||
|
||||
// Get the address of the command data.
|
||||
detail::ioctl_arg_type* data()
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
// Get the address of the command data.
|
||||
const detail::ioctl_arg_type* data() const
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ioctl_arg_type value_;
|
||||
};
|
||||
|
||||
// I/O control command for getting number of bytes available.
|
||||
class bytes_readable
|
||||
{
|
||||
public:
|
||||
// Default constructor.
|
||||
bytes_readable()
|
||||
: value_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct with a specific command value.
|
||||
bytes_readable(std::size_t value)
|
||||
: value_(static_cast<detail::ioctl_arg_type>(value))
|
||||
{
|
||||
}
|
||||
|
||||
// Get the name of the IO control command.
|
||||
int name() const
|
||||
{
|
||||
return FIONREAD;
|
||||
}
|
||||
|
||||
// Set the value of the I/O control command.
|
||||
void set(std::size_t value)
|
||||
{
|
||||
value_ = static_cast<detail::ioctl_arg_type>(value);
|
||||
}
|
||||
|
||||
// Get the current value of the I/O control command.
|
||||
std::size_t get() const
|
||||
{
|
||||
return static_cast<std::size_t>(value_);
|
||||
}
|
||||
|
||||
// Get the address of the command data.
|
||||
detail::ioctl_arg_type* data()
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
// Get the address of the command data.
|
||||
const detail::ioctl_arg_type* data() const
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ioctl_arg_type value_;
|
||||
};
|
||||
|
||||
} // namespace io_control
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_IO_CONTROL_HPP
|