diff options
author | ryoon <ryoon> | 2014-03-20 21:02:00 +0000 |
---|---|---|
committer | ryoon <ryoon> | 2014-03-20 21:02:00 +0000 |
commit | 15eca58bdc15d136d9cb8d7947c0c474c2aa8787 (patch) | |
tree | ce0e2ea91f9a3039c60cbb36bb260a45a3e1dba7 /www/firefox | |
parent | 336d8777d1e36844c7a265e311c66733b5629870 (diff) | |
download | pkgsrc-15eca58bdc15d136d9cb8d7947c0c474c2aa8787.tar.gz |
Update to 28.0
Changelog:
NEW
VP9 video decoding implemented
NEW
Mac OS X: Notification Center support for web notifications
NEW
Horizontal HTML5 audio/video volume control
NEW
Support for Opus in WebM
CHANGED
Now that spdy/3 is implemented support for spdy/2 has been removed and servers without spdy/3 will negotiate to http/1 without any penalty
DEVELOPER
Support for MathML 2.0 'mathvariant' attribute
DEVELOPER
Background thread hang reporting
DEVELOPER
Support for multi-line flexbox in layout
FIXED
Various security fixes
Fixed in Firefox 28
MFSA 2014-32 Out-of-bounds write through TypedArrayObject after neutering
MFSA 2014-31 Out-of-bounds read/write through neutering ArrayBuffer objects
MFSA 2014-30 Use-after-free in TypeObject
MFSA 2014-29 Privilege escalation using WebIDL-implemented APIs
MFSA 2014-28 SVG filters information disclosure through feDisplacementMap
MFSA 2014-27 Memory corruption in Cairo during PDF font rendering
MFSA 2014-26 Information disclosure through polygon rendering in MathML
MFSA 2014-25 Firefox OS DeviceStorageFile object vulnerable to relative path escape
MFSA 2014-24 Android Crash Reporter open to manipulation
MFSA 2014-23 Content Security Policy for data: documents not preserved by session restore
MFSA 2014-22 WebGL content injection from one domain to rendering in another
MFSA 2014-21 Local file access via Open Link in new tab
MFSA 2014-20 onbeforeunload and Javascript navigation DOS
MFSA 2014-19 Spoofing attack on WebRTC permission prompt
MFSA 2014-18 crypto.generateCRMFRequest does not validate type of key
MFSA 2014-17 Out of bounds read during WAV file decoding
MFSA 2014-16 Files extracted during updates are not always read only
MFSA 2014-15 Miscellaneous memory safety hazards (rv:28.0 / rv:24.4)
Diffstat (limited to 'www/firefox')
62 files changed, 3149 insertions, 3953 deletions
diff --git a/www/firefox/Makefile b/www/firefox/Makefile index f9363f91b74..954335a1e9d 100644 --- a/www/firefox/Makefile +++ b/www/firefox/Makefile @@ -1,12 +1,11 @@ -# $NetBSD: Makefile,v 1.155 2014/03/12 23:41:33 ryoon Exp $ +# $NetBSD: Makefile,v 1.156 2014/03/20 21:02:00 ryoon Exp $ FIREFOX_VER= ${MOZ_BRANCH}${MOZ_BRANCH_MINOR} -MOZ_BRANCH= 27.0 -MOZ_BRANCH_MINOR= .1 +MOZ_BRANCH= 28.0 +MOZ_BRANCH_MINOR= DISTNAME= firefox-${FIREFOX_VER}.source PKGNAME= firefox-${MOZ_BRANCH}${MOZ_BRANCH_MINOR:S/b/beta/:S/esr//} -PKGREVISION= 1 CATEGORIES= www MASTER_SITES= ${MASTER_SITE_MOZILLA:=firefox/releases/${FIREFOX_VER}/source/} MASTER_SITES+= ${MASTER_SITE_MOZILLA_ALL:=firefox/releases/${FIREFOX_VER}/source/} diff --git a/www/firefox/PLIST b/www/firefox/PLIST index 5147e997605..81f2dd5d07b 100644 --- a/www/firefox/PLIST +++ b/www/firefox/PLIST @@ -1,4 +1,4 @@ -@comment $NetBSD: PLIST,v 1.77 2014/02/08 09:36:00 ryoon Exp $ +@comment $NetBSD: PLIST,v 1.78 2014/03/20 21:02:00 ryoon Exp $ bin/firefox lib/firefox/application.ini lib/firefox/browser/blocklist.xml @@ -119,10 +119,12 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/debugger.xul lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.css lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.js lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.xhtml +lib/firefox/browser/chrome/browser/content/browser/devtools/framework/options-panel.css lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-options.js lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-options.xul +lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-process-window.js +lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-process-window.xul lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-window.xul -lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox.css lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox.xul lib/firefox/browser/chrome/browser/content/browser/devtools/inspector/inspector.css lib/firefox/browser/chrome/browser/content/browser/devtools/inspector/inspector.xul @@ -135,7 +137,6 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor-controlle lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor-view.js lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor.css lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor.xul -lib/firefox/browser/chrome/browser/content/browser/devtools/orion.js lib/firefox/browser/chrome/browser/content/browser/devtools/profiler.xul lib/firefox/browser/chrome/browser/content/browser/devtools/profiler/cleopatra/css/devtools.css lib/firefox/browser/chrome/browser/content/browser/devtools/profiler/cleopatra/css/tree.css @@ -156,7 +157,8 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/scratchpad.js lib/firefox/browser/chrome/browser/content/browser/devtools/scratchpad.xul lib/firefox/browser/chrome/browser/content/browser/devtools/shadereditor.js lib/firefox/browser/chrome/browser/content/browser/devtools/shadereditor.xul -lib/firefox/browser/chrome/browser/content/browser/devtools/source-editor-overlay.xul +lib/firefox/browser/chrome/browser/content/browser/devtools/spectrum-frame.xhtml +lib/firefox/browser/chrome/browser/content/browser/devtools/spectrum.css lib/firefox/browser/chrome/browser/content/browser/devtools/splitview.css lib/firefox/browser/chrome/browser/content/browser/devtools/styleeditor.css lib/firefox/browser/chrome/browser/content/browser/devtools/styleeditor.xul @@ -247,7 +249,6 @@ lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/applic lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/applications.xul lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/content.js lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/content.xul -lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/landing.xul lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/main.js lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/main.xul lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/preferences.js @@ -346,6 +347,7 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/actionicon-tab.png lib/firefox/browser/chrome/browser/skin/classic/browser/browser.css lib/firefox/browser/chrome/browser/skin/classic/browser/click-to-play-warning-stripes.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/alerticon-warning.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/add.svg lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/connection-footer.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/device.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/error.svg @@ -387,6 +389,7 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl-start.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/close.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-console.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-paintflashing.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-responsivemode.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-scratchpad.png @@ -409,6 +412,9 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/debugger.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dock-bottom.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dock-side.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dropmarker.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-breakpoint.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-debug-location.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-error.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/floating-scrollbars-light.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/floating-scrollbars.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/font-inspector.css @@ -425,12 +431,6 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/markup-view.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/netmonitor.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/noise.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/option-icon.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-breakpoint.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-container.css -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-debug-location.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-error.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-task.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/profiler-stopwatch.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/profiler.css lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/responsive-background.png @@ -455,7 +455,14 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-profiler.p lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-scratchpad.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-styleeditor.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-webconsole.png -lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/toolbox.css +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-dark.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-dark@2x.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-light.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-light@2x.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-dark.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-dark@2x.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-light.png +lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-light@2x.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/undock.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/vview-delete.png lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/vview-edit.png @@ -615,7 +622,6 @@ lib/firefox/browser/chrome/en-US/locale/browser/devtools/sourceeditor.properties lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleeditor.dtd lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleeditor.properties lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleinspector.dtd -lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleinspector.properties lib/firefox/browser/chrome/en-US/locale/browser/devtools/tilt.properties lib/firefox/browser/chrome/en-US/locale/browser/devtools/toolbox.dtd lib/firefox/browser/chrome/en-US/locale/browser/devtools/toolbox.properties @@ -698,6 +704,7 @@ lib/firefox/browser/chrome/pdfjs/content/PdfJs.jsm lib/firefox/browser/chrome/pdfjs/content/PdfJsTelemetry.jsm lib/firefox/browser/chrome/pdfjs/content/build/pdf.js lib/firefox/browser/chrome/pdfjs/content/build/pdf.worker.js +lib/firefox/browser/chrome/pdfjs/content/default_preferences.js lib/firefox/browser/chrome/pdfjs/content/network.js lib/firefox/browser/chrome/pdfjs/content/web/debugger.js lib/firefox/browser/chrome/pdfjs/content/web/images/annotation-check.svg @@ -806,7 +813,6 @@ lib/firefox/browser/modules/devtools/CmdScratchpad.jsm lib/firefox/browser/modules/devtools/CmdTilt.jsm lib/firefox/browser/modules/devtools/Commands.jsm lib/firefox/browser/modules/devtools/DOMHelpers.jsm -lib/firefox/browser/modules/devtools/DebuggerProcess.jsm lib/firefox/browser/modules/devtools/DeveloperToolbar.jsm lib/firefox/browser/modules/devtools/FloatingScrollbars.jsm lib/firefox/browser/modules/devtools/Jsbeautify.jsm @@ -818,6 +824,7 @@ lib/firefox/browser/modules/devtools/StyleEditorPanel.jsm lib/firefox/browser/modules/devtools/StyleEditorUI.jsm lib/firefox/browser/modules/devtools/StyleEditorUtil.jsm lib/firefox/browser/modules/devtools/StyleSheetEditor.jsm +lib/firefox/browser/modules/devtools/ToolboxProcess.jsm lib/firefox/browser/modules/devtools/VariablesView.jsm lib/firefox/browser/modules/devtools/VariablesViewController.jsm lib/firefox/browser/modules/devtools/ViewHelpers.jsm @@ -828,11 +835,12 @@ lib/firefox/browser/modules/devtools/app-manager/connection-store.js lib/firefox/browser/modules/devtools/app-manager/device-store.js lib/firefox/browser/modules/devtools/app-manager/simulators-store.js lib/firefox/browser/modules/devtools/app-manager/webapps-store.js -lib/firefox/browser/modules/devtools/debugger/debugger-panel.js +lib/firefox/browser/modules/devtools/debugger/panel.js lib/firefox/browser/modules/devtools/framework/sidebar.js lib/firefox/browser/modules/devtools/framework/target.js lib/firefox/browser/modules/devtools/framework/toolbox-hosts.js lib/firefox/browser/modules/devtools/framework/toolbox-options.js +lib/firefox/browser/modules/devtools/framework/toolbox-process-window.js lib/firefox/browser/modules/devtools/framework/toolbox.js lib/firefox/browser/modules/devtools/gDevTools.jsm lib/firefox/browser/modules/devtools/gcli.jsm @@ -844,7 +852,7 @@ lib/firefox/browser/modules/devtools/inspector/selector-search.js lib/firefox/browser/modules/devtools/main.js lib/firefox/browser/modules/devtools/markupview/html-editor.js lib/firefox/browser/modules/devtools/markupview/markup-view.js -lib/firefox/browser/modules/devtools/netmonitor/netmonitor-panel.js +lib/firefox/browser/modules/devtools/netmonitor/panel.js lib/firefox/browser/modules/devtools/profiler/cleopatra.js lib/firefox/browser/modules/devtools/profiler/commands.js lib/firefox/browser/modules/devtools/profiler/consts.js @@ -862,12 +870,10 @@ lib/firefox/browser/modules/devtools/shared/observable-object.js lib/firefox/browser/modules/devtools/shared/telemetry.js lib/firefox/browser/modules/devtools/shared/theme-switching.js lib/firefox/browser/modules/devtools/shared/undo.js +lib/firefox/browser/modules/devtools/shared/widgets/Spectrum.js lib/firefox/browser/modules/devtools/shared/widgets/Tooltip.js lib/firefox/browser/modules/devtools/sourceeditor/debugger.js lib/firefox/browser/modules/devtools/sourceeditor/editor.js -lib/firefox/browser/modules/devtools/sourceeditor/source-editor-orion.jsm -lib/firefox/browser/modules/devtools/sourceeditor/source-editor-ui.jsm -lib/firefox/browser/modules/devtools/sourceeditor/source-editor.jsm lib/firefox/browser/modules/devtools/styleinspector/computed-view.js lib/firefox/browser/modules/devtools/styleinspector/rule-view.js lib/firefox/browser/modules/devtools/styleinspector/style-inspector.js @@ -894,16 +900,19 @@ lib/firefox/browser/modules/sessionstore/PageStyle.jsm lib/firefox/browser/modules/sessionstore/PrivacyLevel.jsm lib/firefox/browser/modules/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm lib/firefox/browser/modules/sessionstore/SessionCookies.jsm +lib/firefox/browser/modules/sessionstore/SessionFile.jsm lib/firefox/browser/modules/sessionstore/SessionHistory.jsm lib/firefox/browser/modules/sessionstore/SessionMigration.jsm lib/firefox/browser/modules/sessionstore/SessionSaver.jsm lib/firefox/browser/modules/sessionstore/SessionStorage.jsm lib/firefox/browser/modules/sessionstore/SessionStore.jsm lib/firefox/browser/modules/sessionstore/SessionWorker.js +lib/firefox/browser/modules/sessionstore/TabAttributes.jsm +lib/firefox/browser/modules/sessionstore/TabState.jsm lib/firefox/browser/modules/sessionstore/TabStateCache.jsm lib/firefox/browser/modules/sessionstore/TextAndScrollData.jsm +lib/firefox/browser/modules/sessionstore/Utils.jsm lib/firefox/browser/modules/sessionstore/XPathGenerator.jsm -lib/firefox/browser/modules/sessionstore/_SessionFile.jsm lib/firefox/browser/modules/tabview/utils.jsm lib/firefox/browser/modules/webappsUI.jsm lib/firefox/browser/modules/webrtcUI.jsm @@ -946,6 +955,8 @@ lib/firefox/chrome/en-US/locale/en-US/global/appPicker.dtd lib/firefox/chrome/en-US/locale/en-US/global/appstrings.properties lib/firefox/chrome/en-US/locale/en-US/global/brand.dtd lib/firefox/chrome/en-US/locale/en-US/global/browser.properties +lib/firefox/chrome/en-US/locale/en-US/global/charsetMenu.dtd +lib/firefox/chrome/en-US/locale/en-US/global/charsetMenu.properties lib/firefox/chrome/en-US/locale/en-US/global/charsetOverlay.dtd lib/firefox/chrome/en-US/locale/en-US/global/charsetTitles.properties lib/firefox/chrome/en-US/locale/en-US/global/commonDialog.dtd @@ -964,6 +975,7 @@ lib/firefox/chrome/en-US/locale/en-US/global/customizeToolbar.properties lib/firefox/chrome/en-US/locale/en-US/global/dateFormat.properties lib/firefox/chrome/en-US/locale/en-US/global/datetimepicker.dtd lib/firefox/chrome/en-US/locale/en-US/global/devtools/debugger.properties +lib/firefox/chrome/en-US/locale/en-US/global/devtools/styleinspector.properties lib/firefox/chrome/en-US/locale/en-US/global/dialog.properties lib/firefox/chrome/en-US/locale/en-US/global/dialogOverlay.dtd lib/firefox/chrome/en-US/locale/en-US/global/dom/dom.properties @@ -1159,8 +1171,10 @@ lib/firefox/chrome/toolkit/content/global/aboutTelemetry.css lib/firefox/chrome/toolkit/content/global/aboutTelemetry.js lib/firefox/chrome/toolkit/content/global/aboutTelemetry.xhtml lib/firefox/chrome/toolkit/content/global/accessibility/AccessFu.css +lib/firefox/chrome/toolkit/content/global/accessibility/clicked.ogg lib/firefox/chrome/toolkit/content/global/accessibility/content-script.js -lib/firefox/chrome/toolkit/content/global/accessibility/tick.wav +lib/firefox/chrome/toolkit/content/global/accessibility/virtual_cursor_key.ogg +lib/firefox/chrome/toolkit/content/global/accessibility/virtual_cursor_move.ogg lib/firefox/chrome/toolkit/content/global/alerts/alert.css lib/firefox/chrome/toolkit/content/global/alerts/alert.js lib/firefox/chrome/toolkit/content/global/alerts/alert.xul @@ -1238,6 +1252,7 @@ lib/firefox/chrome/toolkit/content/global/filepicker.xul lib/firefox/chrome/toolkit/content/global/findUtils.js lib/firefox/chrome/toolkit/content/global/finddialog.js lib/firefox/chrome/toolkit/content/global/finddialog.xul +lib/firefox/chrome/toolkit/content/global/forms.js lib/firefox/chrome/toolkit/content/global/globalOverlay.js lib/firefox/chrome/toolkit/content/global/globalOverlay.xul lib/firefox/chrome/toolkit/content/global/inlineSpellCheckUI.js @@ -1519,7 +1534,8 @@ lib/firefox/chrome/toolkit/skin/classic/global/media/throbber.png lib/firefox/chrome/toolkit/skin/classic/global/media/unmuteButton.png lib/firefox/chrome/toolkit/skin/classic/global/media/videoClickToPlayButton.svg lib/firefox/chrome/toolkit/skin/classic/global/media/videocontrols.css -lib/firefox/chrome/toolkit/skin/classic/global/media/volumeThumb.png +lib/firefox/chrome/toolkit/skin/classic/global/media/volume-empty.png +lib/firefox/chrome/toolkit/skin/classic/global/media/volume-full.png lib/firefox/chrome/toolkit/skin/classic/global/menu.css lib/firefox/chrome/toolkit/skin/classic/global/menulist.css lib/firefox/chrome/toolkit/skin/classic/global/netError.css @@ -1641,8 +1657,12 @@ lib/firefox/chrome/toolkit/skin/classic/mozapps/update/updates.css lib/firefox/chrome/toolkit/skin/classic/mozapps/viewsource/viewsource.css lib/firefox/chrome/toolkit/skin/classic/mozapps/xpinstall/xpinstallConfirm.css lib/firefox/chrome/toolkit/skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png +lib/firefox/components/ActivityMessageConfigurator.js +lib/firefox/components/ActivityOptions.js +lib/firefox/components/ActivityProxy.js +lib/firefox/components/ActivityRequestHandler.js +lib/firefox/components/ActivityWrapper.js lib/firefox/components/AlarmsManager.js -lib/firefox/components/AppProtocolHandler.js lib/firefox/components/AppsService.js lib/firefox/components/BrowserElementParent.js lib/firefox/components/ColorAnalyzer.js @@ -1667,8 +1687,9 @@ lib/firefox/components/PlacesCategoriesStarter.js lib/firefox/components/Push.js lib/firefox/components/PushServiceLauncher.js lib/firefox/components/SettingsManager.js -lib/firefox/components/SettingsService.js lib/firefox/components/SiteSpecificUserAgent.js +lib/firefox/components/SystemMessageInternal.js +lib/firefox/components/SystemMessageManager.js lib/firefox/components/TCPServerSocket.js lib/firefox/components/TCPSocket.js lib/firefox/components/TCPSocketParentIntermediary.js @@ -1785,6 +1806,7 @@ lib/firefox/modules/AppsServiceChild.jsm lib/firefox/modules/AppsUtils.jsm lib/firefox/modules/AsyncShutdown.jsm lib/firefox/modules/AsyncSpellCheckTestHelper.jsm +lib/firefox/modules/AutoCompleteE10S.jsm lib/firefox/modules/BackgroundPageThumbs.jsm lib/firefox/modules/BookmarkHTMLUtils.jsm lib/firefox/modules/BookmarkJSONUtils.jsm @@ -1792,6 +1814,7 @@ lib/firefox/modules/BrowserElementParent.jsm lib/firefox/modules/BrowserElementPromptService.jsm lib/firefox/modules/CSPUtils.jsm lib/firefox/modules/CertUtils.jsm +lib/firefox/modules/CharsetMenu.jsm lib/firefox/modules/ChromeManifestParser.jsm lib/firefox/modules/ClusterLib.js lib/firefox/modules/ColorAnalyzer_worker.js @@ -1832,6 +1855,8 @@ lib/firefox/modules/FormHistory.jsm lib/firefox/modules/FrameWorker.jsm lib/firefox/modules/FrameWorkerContent.js lib/firefox/modules/FreeSpaceWatcher.jsm +lib/firefox/modules/FxAccounts.jsm +lib/firefox/modules/FxAccountsClient.jsm lib/firefox/modules/Geometry.jsm lib/firefox/modules/HealthReport.jsm lib/firefox/modules/Http.jsm @@ -1919,19 +1944,19 @@ lib/firefox/modules/WebappOSUtils.jsm lib/firefox/modules/Webapps.jsm lib/firefox/modules/WebappsInstaller.jsm lib/firefox/modules/WindowDraggingUtils.jsm +lib/firefox/modules/WindowsPrefSync.jsm lib/firefox/modules/WorkerAPI.jsm lib/firefox/modules/XPCOMUtils.jsm lib/firefox/modules/XPIProvider.jsm lib/firefox/modules/XPIProviderUtils.js lib/firefox/modules/accessibility/AccessFu.jsm +lib/firefox/modules/accessibility/Constants.jsm lib/firefox/modules/accessibility/EventManager.jsm -lib/firefox/modules/accessibility/Makefile.in lib/firefox/modules/accessibility/OutputGenerator.jsm lib/firefox/modules/accessibility/Presentation.jsm lib/firefox/modules/accessibility/TouchAdapter.jsm lib/firefox/modules/accessibility/TraversalRules.jsm lib/firefox/modules/accessibility/Utils.jsm -lib/firefox/modules/accessibility/jar.mn lib/firefox/modules/commonjs/method/History.md lib/firefox/modules/commonjs/method/License.md lib/firefox/modules/commonjs/method/Readme.md diff --git a/www/firefox/distinfo b/www/firefox/distinfo index 5f4875ca305..5db7c78bd76 100644 --- a/www/firefox/distinfo +++ b/www/firefox/distinfo @@ -1,38 +1,60 @@ -$NetBSD: distinfo,v 1.133 2014/02/21 16:17:47 ryoon Exp $ +$NetBSD: distinfo,v 1.134 2014/03/20 21:02:00 ryoon Exp $ -SHA1 (firefox-27.0.1.source.tar.bz2) = 29dc759e36f2b9381e80ac48ce59635ea25033dc -RMD160 (firefox-27.0.1.source.tar.bz2) = c6849fd4af75d8e6cb559b22bb7e3d1a616e270c -Size (firefox-27.0.1.source.tar.bz2) = 129249507 bytes -SHA1 (patch-aa) = e510bfad9f4d2950e5751d2a8d15971dcad75fb0 +SHA1 (firefox-28.0.source.tar.bz2) = f78517836ceca0cd2a0d3db1f282985c616e3fae +RMD160 (firefox-28.0.source.tar.bz2) = 71124b36dca319eaa0de268ce4f6133f0ceca4f9 +Size (firefox-28.0.source.tar.bz2) = 134968426 bytes +SHA1 (patch-aa) = c50d30d8bf2f8dbba938e4f5542b9d8b6e395e4e SHA1 (patch-ak) = 971ddb1f12b14bcee604c9d7e72da5e7bf47d9be SHA1 (patch-al) = 553c6042a98e4b381a46eec50c02cff349d88bd2 -SHA1 (patch-ao) = 3c777c8caf7f951a711c79612c08cee2cd338a57 -SHA1 (patch-as) = 62be47c27d74dedf70f048b3ac3ce99a2b4f7b3c +SHA1 (patch-ao) = ca7e6723a10b9f6e3306cd12557e1856727edee9 +SHA1 (patch-as) = 3ce6e71d638ac1b6dec6737c92246e2dc7ff5d84 SHA1 (patch-bf) = 75c971043e9f693203d6bd670b2c20c4952a7756 SHA1 (patch-bg) = d6c02294765265d9e85cf49c22320d88573c2e25 SHA1 (patch-bi) = 3dd927d93431afe000cd4a45b4d9920e63158a85 +SHA1 (patch-browser_app_nsBrowserApp.cpp) = 348227a30b25fda41b4f79235fc623f64ca8e8ba SHA1 (patch-browser_app_profile_firefox.js) = 108efbe1ae65669912d2f76caec546753e1ac8f3 -SHA1 (patch-browser_installer_package-manifest.in) = a00ac3c6ddedd316c7350ad9867a1a68cce974e1 +SHA1 (patch-browser_installer_package-manifest.in) = d5792a3c5dd7498d24ac0426aacf7d0b9a842c67 SHA1 (patch-browser_locales_en-US_chrome_browser-region_region.properties) = 284d62596718d7f372c4e5214fd05adec043c93a SHA1 (patch-browser_locales_en-US_searchplugins_duckduckgo.xml) = 69eca52185ac868e95041b5d87611ee32c2b6330 SHA1 (patch-browser_locales_en-US_searchplugins_list.txt) = a6677b3a195b6c956858326e4e7474441823a47f +SHA1 (patch-browser_themes_shared_devtools_common.css) = 37947ab5b523af83b58fd2dce3ed13599e5da9ef +SHA1 (patch-browser_themes_shared_devtools_highlighter.inc.css) = 7c2a81b9f62a34d6d93b142508771f90954a6080 SHA1 (patch-build_autoconf_nss.m4) = bf65db126705a3a1ba294418b9380683ea401fc7 +SHA1 (patch-build_pgo_profileserver.py) = 8666187258e47c037f2065a19a5b38946fdc0f6c +SHA1 (patch-config_Makefile.in) = 5ceb934dfc4bb02c8b1968a7bf8d004348a7ced1 SHA1 (patch-config_baseconfig.mk) = 9056301a239b7a927ee06a8f53702aece9780dc4 +SHA1 (patch-config_external_moz.build) = 52de4e24f4aa7446554c5906f9b475dbe956be5c SHA1 (patch-config_stl__wrappers_ios) = 00d723e2f2f252485350ede5833f0bb84c1235c1 SHA1 (patch-config_stl__wrappers_ostream) = 7be7fe36704ffbdc070a113b46b4f391a598206b -SHA1 (patch-config_system-headers) = b091819a932f86a19f98ea71787447c9899138c6 +SHA1 (patch-config_system-headers) = d74398cc427ebd436f6c3871f123feec7afa5926 SHA1 (patch-config_system__wrappers_unwind.h) = b3bdac0710179b9c8f8eabd824216d0114504491 +SHA1 (patch-content_base_src_Makefile.in) = 44016467828b787343444ba62c12637988e0f903 +SHA1 (patch-content_media_Makefile.in) = 56ecae4124aad54cffeba63c6e094e7a305c5b4e +SHA1 (patch-content_media_gstreamer_GStreamerAllocator.cpp) = 1659560ccc68ef5e3d1b41be98a489d53d9e359f +SHA1 (patch-content_media_gstreamer_GStreamerAllocator.h) = c2dd30332b3a13aea81d0e60ae2da535973cdc57 +SHA1 (patch-content_media_gstreamer_GStreamerFormatHelper.cpp) = 5728aad1f00f8600dd5c512c727640883c2bf225 +SHA1 (patch-content_media_gstreamer_GStreamerFunctionList.h) = 6bbcf08a4f5c710bf08a0e94945fcbf1b3e8e6bf +SHA1 (patch-content_media_gstreamer_GStreamerLoader.cpp) = a86bc37efb7012a9a360dd41b9f84d87c783bdda +SHA1 (patch-content_media_gstreamer_GStreamerLoader.h) = 0458ab4ecab7f76133c31af2ed952e0eeff71164 +SHA1 (patch-content_media_gstreamer_GStreamerReader-0.10.cpp) = ed9853effc8ee2999bdad34a6d59eb9e2897c43a +SHA1 (patch-content_media_gstreamer_GStreamerReader.cpp) = bf26c4e2bdf3cfa644470d0a0dc8ff48f1ad42a1 +SHA1 (patch-content_media_gstreamer_GStreamerReader.h) = 118f83ebdec7bcda4f0ced8064a9b3c6cad78172 +SHA1 (patch-content_media_gstreamer_moz.build) = c38bd0d432577b55429ae5466b1b02c7b6fd1901 +SHA1 (patch-content_media_test_manifest.js) = 5b98d9eb16f898211fc0e30d821303bf72e8aaeb SHA1 (patch-dom_plugins_ipc_PluginModuleChild.cpp) = 69b0a51d733cd52e7d200052362e0faf4ec918f1 SHA1 (patch-dom_plugins_ipc_PluginModuleChild.h) = 0a7f3167e939822013ae6195406657453578453e -SHA1 (patch-extensions_auth_nsAuthGSSAPI.cpp) = 548886fc4a86a988f3f91650061ddc04f37653a8 SHA1 (patch-extensions_spellcheck_hunspell_src_mozHunspell.cpp) = a2a0652d0eac018fda06e729bf5ba786dd8a3866 SHA1 (patch-gfx__skia__include__core__SkPreConfig.h) = 6f99cf0eb5d4617d529c378707f537bc1e5cb28f SHA1 (patch-gfx_graphite2_src_Bidi.cpp) = 5e80b4a32a47ae44d237fec69ea87bdd612a76ce -SHA1 (patch-gfx_skia_moz.build) = dd83548d5eb7c3495932dd7df94c699c8c82270e +SHA1 (patch-gfx_moz.build) = a98bda4727538f4a0f09a20b84f9dd883edaf7d9 +SHA1 (patch-gfx_skia_Makefile.in) = df1592fcab275a13e7015c9d73283f4326898186 +SHA1 (patch-gfx_skia_moz.build) = 1eb1b2c8948f7faaab267cace79f179fb258523c SHA1 (patch-gfx_skia_src_utils_SkThreadUtils__pthread__linux.cpp) = 916d61bd9613df0fe2b6cfd0d6b1e49ffc40da5f +SHA1 (patch-gfx_thebes_Makefile.in) = 42c12be1c2064d448c88edb542cdea0451f8f372 SHA1 (patch-image_decoders_nsJPEGDecoder.cpp) = e5df11499b1ec14e1d4c9a1408c0611d1c4e0574 SHA1 (patch-intl_hyphenation_src_hnjalloc.h) = 7fcc7b0fcf5a33486214197e925fbc8e6e22e2ee -SHA1 (patch-ipc_chromium_Makefile.in) = 61ada3484c1ec0c07ee537aa7dd32e2c8411c10f +SHA1 (patch-intl_unicharutil_util_Makefile.in) = 6ea0831e6cdcae43f8253a97766e783ad7b84b55 +SHA1 (patch-ipc_chromium_Makefile.in) = 3a1f5b218217fc8e5e9a07195054618071c38059 SHA1 (patch-ipc_chromium_src_base_base__paths.h) = 7bc83577a9678542db4dff7dda19d751ff6d78c1 SHA1 (patch-ipc_chromium_src_base_debug__util__posix.cc) = 677f0b5ccdcde7a8551f2d07d2a472361a5da03f SHA1 (patch-ipc_chromium_src_base_file__util.h) = 9d6d074b1692c6b4e722bfac8d67c66040a6fa76 @@ -47,50 +69,56 @@ SHA1 (patch-ipc_chromium_src_base_sys__info__posix.cc) = 30646e3cd2d010a75e2a385 SHA1 (patch-ipc_chromium_src_base_time__posix.cc) = 337a0b4a5d51d68c7699b79c7591b953ea23ca67 SHA1 (patch-ipc_chromium_src_build_build__config.h) = af5a10df7d8fe9715f0e43cd6be14f8f20c53517 SHA1 (patch-ipc_chromium_src_chrome_common_transport__dib.h) = 7af18973c005d7b144a225bacf41833e059cb400 -SHA1 (patch-ipc_glue_GeckoChildProcessHost.cpp) = fe9ac2d0af8dd4757c93f50e6f74a31697f7e23c +SHA1 (patch-ipc_glue_GeckoChildProcessHost.cpp) = 0fccd3224433017c7214b2615aa2c6c2d8ed658f SHA1 (patch-ipc_ipdl_ipdl_lower.py) = 4025c0a4e149d9b2087331e10b342734fa77a905 SHA1 (patch-js__src__vm__SPSProfiler.cpp) = ac6da8a477cd0a768a513462b7bc3b871fd280f1 -SHA1 (patch-js_src_Makefile.in) = 2a3a52ec33b37b9df2047bfb35537689cca3ebb2 -SHA1 (patch-js_src_config_system-headers) = 405921c2638f6bf37f33b7d6b162addbfb162dea +SHA1 (patch-js_src_Makefile.in) = f6ce5f02a9292e3e524424c5e810850232efe524 +SHA1 (patch-js_src_config_system-headers) = db1389af40dc0386ed8c3491a377668f5d29b6a1 SHA1 (patch-js_src_ctypes_CTypes.h) = 768a084239f92a424c1c7dc9eaaf9be9456ca9f0 SHA1 (patch-js_src_frontend_ParseMaps.cpp) = c00117d79b78904bc50a1d664a8fc0e4e339bfbc SHA1 (patch-js_src_jsmath.cpp) = 7d4993ae91e9b5e6820358165603819aefb586f9 -SHA1 (patch-mb) = 24daa34185852f4f865bcd42041fc1cb693d9fe7 +SHA1 (patch-mb) = b661abce429a88554fca6c930b4dbf71ba6bb5cb SHA1 (patch-media_libcubeb_src_cubeb__alsa.c) = 5ef0de0ac875334e959ff0d4bfa43a2e5ab087b9 SHA1 (patch-media_libpng_pngpriv.h) = c9cefd1b5dd85fbd0c875c3f9bc108975398fe3a SHA1 (patch-media_libsoundtouch_src_cpu__detect__x86.cpp) = 061b46d1ee33c055a5b39e6b20f47b80bcde0c86 +SHA1 (patch-media_libtheora_Makefile.in) = 80ac9cb20760fe4d94047f7cb1c6a16bbdd6b505 +SHA1 (patch-media_libtremor_Makefile.in) = 497d03646caa721bdd129de365aadea8466043af +SHA1 (patch-media_libvorbis_Makefile.in) = fd1ce15268eed9c97dd0774398d559cdbed63e53 SHA1 (patch-media_mtransport_third__party_nrappkit_src_port_generic_include_sys_queue.h) = 056172e54652caa60b6fee26e3073a6da83e734c SHA1 (patch-media_webrtc_signaling_signaling.gyp) = ed52bb96a7ba6d7126b09871fe5ac81983cefdc1 -SHA1 (patch-media_webrtc_signaling_test_Makefile.in) = 7b05fe304cde8adbaa46ff8960978f96848541b6 +SHA1 (patch-media_webrtc_signaling_test_Makefile.in) = 4a9f9d3e4be79d711aa1f44f2982ec660ce5b15a SHA1 (patch-media_webrtc_trunk_webrtc_build_common.gypi) = ac7250e37f30353af0a7789b7234f3bc56a3ecd7 -SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc) = a7dd28746ea1c839e03c00f40985d73dd89dfd72 -SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc) = 076cf414a1a2ee270105a043517bbbb341382f49 +SHA1 (patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi) = f67c537662a994101125d8a10d0432c68d28f2ea +SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc) = 3cb1d688a19a9c211cc79fcf1c6879d8a5565433 +SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc) = be78d8d723c0560e08476a8d60b909772da49579 SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_video__capture.gypi) = 4721f01a89ef353c9b743b3cfefda4877d5283d9 -SHA1 (patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp) = f5af60a298e9e22499f3c743b3e140dbf4a83951 +SHA1 (patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp) = 78a9522f0e37cfc3ec8267e6c15de9dba0ec7ff3 +SHA1 (patch-memory_jemalloc_Makefile.in) = 772e996c8da254f952d0f3a0c9325a177c838543 SHA1 (patch-memory_mozalloc_fallible.h) = 8a60151465a07570db9636313f504004d73941d5 SHA1 (patch-memory_mozalloc_mozalloc.cpp) = 802af1da05f60fcf8c206568c2adc396e3bb0e06 SHA1 (patch-memory_mozalloc_mozalloc.h) = f2d9fd333ec28c075dfde8a6ee414b67b7f2cd26 SHA1 (patch-memory_mozalloc_mozalloc__abort.cpp) = 9d9036ddd28c7b8ce37860e0120df2997a3a0c59 SHA1 (patch-mfbt_Poison.cpp) = b582943c02f57835451c9eecd004c9912d42ce84 SHA1 (patch-modules_libjar_nsZipArchive.cpp) = 6aff0f8ed42575d8ca36a524e12e9a1f7351004a +SHA1 (patch-netwerk_dns_Makefile.in) = 64b7ba4ec4f984e07c8c911cfb2261b08ea6aa55 SHA1 (patch-netwerk_sctp_src_netinet6_sctp6__usrreq.c) = 31d49db31b1e130f1b455f883e5b7c606d438771 SHA1 (patch-netwerk_sctp_src_netinet_sctp__os__userspace.h) = b3f94ac0f2bd652371fef22c642b14bf30162998 SHA1 (patch-netwerk_sctp_src_netinet_sctp__usrreq.c) = 421b6e071a9934567ccba337033a42208e6e4bd5 SHA1 (patch-netwerk_sctp_src_user__recv__thread.c) = cf26945441f74c581aeb5a8d7435780f4a48a607 SHA1 (patch-netwerk_sctp_src_user__socket.c) = c0b32ed2888b5845ce2b7646b85af8f0728bc7c3 SHA1 (patch-netwerk_sctp_src_user__socketvar.h) = 1b6e2864916ced693b1ab6c1bbdd80a4ffc4f7e4 -SHA1 (patch-netwerk_wifi_moz.build) = acbe49623fe25726a327f49c2568e77fa4b82558 -SHA1 (patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp) = 9c343bef282192e1ac4b0742f160137d394c21b6 +SHA1 (patch-netwerk_wifi_moz.build) = 8c88e5bab2a5e164e97ce568686bd280d4b90bec +SHA1 (patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp) = c5711adc111dc8413a7234e7d5814a0af9ceeecc SHA1 (patch-pb) = 97c9b2e4cefd524dc6ba825f71c3da2a761aa1f4 SHA1 (patch-pc) = 8b2baa88f0983a2fef4f801cf6b1ae425f6c813a SHA1 (patch-rc) = 2733724442a2cb49c5091146fd7e6001af686121 SHA1 (patch-security_manager_ssl_src_JARSignatureVerification.cpp) = e9749dfeb0d3fcb4637935322ffd1e0cad4f8ec3 SHA1 (patch-security_manager_ssl_src_nsNSSComponent.cpp) = c4c96b7d3cb0c5dbcfe3820fd52421eec2592452 -SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__back.jsm) = c18cac4393fb3503b60717d6053e27d41c9f733c -SHA1 (patch-toolkit_library_Makefile.in) = 282e30738328fd447a1ba74a344a22f7fe044b3a +SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm) = b809c17231d1d5eecaed6f6aa0ddb34685fb6800 +SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__back.jsm) = 274b06bd4bfea5b6d7d67c0d39a484d179ed560c +SHA1 (patch-toolkit_library_Makefile.in) = ccd62ca282cf41eeb6637672920083ab269e1c33 SHA1 (patch-toolkit_mozapps_update_updater_updater.cpp) = 6936e5408fc7f0110768f3fc8f27506c0e7879fa SHA1 (patch-toolkit_toolkit.mozbuild) = 0993d50cc02c2b421e6de087dfb0a9cb30562c6b -SHA1 (patch-toolkit_xre_Makefile.in) = 6ad65fa2fd026888cc8345e184daf2a070ea4885 SHA1 (patch-toolkit_xre_nsEmbedFunctions.cpp) = 6ee6fba04a3ecc6596f8aed67f752a1075901fa8 SHA1 (patch-xb) = 30eea880b40cee45d1235d3292fead4b5a54bbaa SHA1 (patch-xc) = 8575fdac2b47966ccfb5e1cc7ca8505163e358c9 @@ -99,13 +127,13 @@ SHA1 (patch-xf) = 1720ae5cf3cf0df6f2e9519c83a332585bdd67bf SHA1 (patch-xg) = b80e660e85b06e4f71146bd41bd4bc0d2e3b6488 SHA1 (patch-xl) = 9555b86c72b2e144e341d6af1dbfbc07cc8c94db SHA1 (patch-xm) = 81e02e410c00175cbb98c646dda90c7adf199657 -SHA1 (patch-xn) = c042e39d93706934ec03c78be3dc6e224ac62c0e -SHA1 (patch-xo) = aae6107dcfaf731bd3e9962d953fb8701fc5f163 -SHA1 (patch-xpcom_base_nsMemoryInfoDumper.cpp) = 245508dc7ad64eb1dc514caf6e85904d440742ca -SHA1 (patch-xpcom_base_nsMemoryReporterManager.cpp) = f23cf57c59faf1b83d54a234e53aad61116da5ca -SHA1 (patch-xpcom_base_nsStackWalk.cpp) = b763f5f3505efbedf51a9544a03d0501d86138b1 +SHA1 (patch-xpcom_base_nsStackWalk.cpp) = 330635b2b0ad1efec6f2296ac1dedd458c9248dc +SHA1 (patch-xpcom_base_nscore.h) = b1a190d8ef4478b882daeceda51584f947555a28 SHA1 (patch-xpcom_ds_TimeStamp.h) = a1fb060f91720eb330f102b28d9373bbdbe96e30 -SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_moz.build) = 67e97ae07ec180da8277371f4b6fa4c56c203ac8 +SHA1 (patch-xpcom_io_nsLocalFileUnix.cpp) = 3de3345eb98ffe78628d5bac672ce4ab5806270e +SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_moz.build) = ee1e09e0352adedf0c50d11db18c7e57238a3b02 +SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S) = b2b81fcdf6591089fcc5de4c8f820e96c0a50256 SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__gcc__x86__unix.cpp) = 8cd42915cd32756b55894a773a1e6d7c012b4467 +SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S) = 1bb4baf0baa223cd87a8cb85b16b37c368c45b94 SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__gcc__x86__unix.cpp) = e9e336817c172187f3e15ddf539a8a2176e3e952 SHA1 (patch-xulrunner_installer_Makefile.in) = 9d32ff87d0962c0406ed38de995c0350dd372e49 diff --git a/www/firefox/patches/patch-aa b/www/firefox/patches/patch-aa index fe429fd67bb..1356e8e81f2 100644 --- a/www/firefox/patches/patch-aa +++ b/www/firefox/patches/patch-aa @@ -1,51 +1,134 @@ -$NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-aa,v 1.21 2014/03/20 21:02:00 ryoon Exp $ ---- configure.in.orig 2013-12-05 16:07:23.000000000 +0000 +--- configure.in.orig 2014-03-15 05:19:10.000000000 +0000 +++ configure.in -@@ -2752,6 +2752,7 @@ EOF - #pragma GCC visibility push(hidden) - #pragma GCC visibility push(default) - #include <string.h> -+#include <iterator> - #pragma GCC visibility pop - - __attribute__ ((visibility ("default"))) void Func() { -@@ -2760,7 +2761,7 @@ __attribute__ ((visibility ("default"))) - } - EOF - ac_cv_have_visibility_builtin_bug=no +@@ -2544,118 +2544,15 @@ MOZ_CXX11 + + AC_LANG_C + +-dnl Check for .hidden assembler directive and visibility attribute. +-dnl Borrowed from glibc configure.in ++dnl Setup default hidden visibility and wrapped system headers. + dnl =============================================================== + if test "$GNU_CC"; then +- AC_CACHE_CHECK(for visibility(hidden) attribute, +- ac_cv_visibility_hidden, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("hidden"))) = 1; +-EOF +- ac_cv_visibility_hidden=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_hidden=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_hidden" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility(default) attribute, +- ac_cv_visibility_default, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("default"))) = 1; +-EOF +- ac_cv_visibility_default=no +- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_default=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_default" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility pragma support, +- ac_cv_visibility_pragma, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +- int foo_hidden = 1; +-#pragma GCC visibility push(default) +- int foo_default = 1; +-EOF +- ac_cv_visibility_pragma=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then +- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then +- ac_cv_visibility_pragma=yes +- fi +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_pragma" = "yes"; then +- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905), +- ac_cv_have_visibility_class_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-struct __attribute__ ((visibility ("default"))) TestStruct { +- static void Init(); +-}; +-__attribute__ ((visibility ("default"))) void TestFunc() { +- TestStruct::Init(); +-} +-EOF +- ac_cv_have_visibility_class_bug=no +- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then +- ac_cv_have_visibility_class_bug=yes +- else +- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then +- ac_cv_have_visibility_class_bug=yes +- fi +- fi +- rm -rf conftest.{c,S} +- ]) +- +- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297), +- ac_cv_have_visibility_builtin_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-#pragma GCC visibility push(default) +-#include <string.h> +-#pragma GCC visibility pop +- +-__attribute__ ((visibility ("default"))) void Func() { +- char c[[100]]; +- memset(c, 0, sizeof(c)); +-} +-EOF +- ac_cv_have_visibility_builtin_bug=no - if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then -+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then - ac_cv_have_visibility_builtin_bug=yes - else - if test `grep -c "@PLT" conftest.S` = 0; then -@@ -3216,14 +3217,22 @@ fi - AC_CACHE_CHECK( - [for res_ninit()], - ac_cv_func_res_ninit, -- [AC_TRY_LINK([ -+ [AC_TRY_RUN([ - #ifdef linux - #define _BSD_SOURCE 1 - #endif -+ #ifdef __NetBSD__ -+ #error use of global _res variable in threaded programs is not portable -+ #endif -+ #include <sys/types.h> -+ #include <netinet/in.h> -+ #include <arpa/nameser.h> - #include <resolv.h> -- ], -- [int foo = res_ninit(&_res);], -+ int main(int argc, char **argv){ -+ int foo = res_ninit(&_res); -+ }], - [ac_cv_func_res_ninit=yes], -+ [ac_cv_func_res_ninit=no], - [ac_cv_func_res_ninit=no]) - ]) - -@@ -3874,6 +3883,14 @@ if test -n "$YASM"; then +- ac_cv_have_visibility_builtin_bug=yes +- else +- if test `grep -c "@PLT" conftest.S` = 0; then +- ac_cv_visibility_builtin_bug=yes +- fi +- fi +- rm -f conftest.{c,S} +- ]) +- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ +- "$ac_cv_have_visibility_class_bug" = "no"; then +- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' +- WRAP_SYSTEM_INCLUDES=1 +- STL_FLAGS='-I$(DIST)/stl_wrappers' +- WRAP_STL_INCLUDES=1 +- else +- VISIBILITY_FLAGS='-fvisibility=hidden' +- fi # have visibility pragma bug +- fi # have visibility pragma +- fi # have visibility(default) attribute +- fi # have visibility(hidden) attribute ++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) ++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) ++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' ++ WRAP_SYSTEM_INCLUDES=1 ++ STL_FLAGS='-I$(DIST)/stl_wrappers' ++ WRAP_STL_INCLUDES=1 + fi # GNU_CC + + # visibility hidden flag for Sun Studio on Solaris +@@ -3724,6 +3621,14 @@ if test -n "$YASM"; then _YASM_BUILD=` echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'` fi @@ -60,7 +143,7 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ if test -z "$SKIP_LIBRARY_CHECKS"; then dnl system JPEG support dnl ======================================================== -@@ -3901,11 +3918,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then +@@ -3751,11 +3656,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then #include <jpeglib.h> ], [ #if JPEG_LIB_VERSION < $MOZJPEG #error "Insufficient JPEG library version ($MOZJPEG required)." @@ -73,7 +156,7 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ MOZ_NATIVE_JPEG=1, AC_MSG_ERROR([Insufficient JPEG library version for --with-system-jpeg])) fi -@@ -4062,6 +4075,22 @@ fi +@@ -3921,6 +3822,22 @@ fi AC_SUBST(MOZ_NATIVE_ICU) dnl ======================================================== @@ -96,20 +179,25 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ dnl Java SDK support dnl ======================================================== -@@ -5281,6 +5310,12 @@ if test -n "$MOZ_WEBRTC"; then - MOZ_VP8_ENCODER=1 +@@ -3955,6 +3872,7 @@ MOZ_SAMPLE_TYPE_FLOAT32= + MOZ_SAMPLE_TYPE_S16= + MOZ_OPUS=1 + MOZ_WEBM=1 ++MOZ_GSTREAMER= + MOZ_DIRECTSHOW= + MOZ_WMF= + MOZ_FMP4= +@@ -5136,6 +5054,9 @@ if test -n "$MOZ_WEBRTC"; then + MOZ_VP8=1 MOZ_VP8_ERROR_CONCEALMENT=1 + dnl with libv4l2 we can support more cameras + PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2) + -+ dnl with libv4l2 we can support more cameras -+ PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2) -+ dnl enable once Signaling lands MOZ_WEBRTC_SIGNALING=1 AC_DEFINE(MOZ_WEBRTC_SIGNALING) -@@ -5307,15 +5342,18 @@ AC_SUBST(MOZ_SRTP) +@@ -5158,15 +5079,18 @@ AC_SUBST(MOZ_SRTP) dnl Use integers over floats for audio on B2G and Android, because audio dnl backends for those platforms don't support floats. @@ -131,7 +219,205 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ dnl ======================================================== dnl = Disable Speech API code -@@ -8276,7 +8314,7 @@ case "$OS_TARGET" in +@@ -5230,6 +5154,40 @@ if test -n "$MOZ_OGG"; then + fi + + dnl ======================================================== ++dnl Check for libogg ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-ogg, ++[ --with-system-ogg Use system libogg (located with pkgconfig)], ++MOZ_NATIVE_OGG=1, ++MOZ_NATIVE_OGG= ) ++ ++if test -n "$MOZ_NATIVE_OGG"; then ++ PKG_CHECK_MODULES(MOZ_OGG, ogg >= 1.2.1) ++fi ++ ++AC_SUBST(MOZ_NATIVE_OGG) ++AC_SUBST(MOZ_OGG_CFLAGS) ++AC_SUBST(MOZ_OGG_LIBS) ++ ++dnl ======================================================== ++dnl Check for libvorbis ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-vorbis, ++[ --with-system-vorbis Use system libvorbis (located with pkgconfig)], ++MOZ_NATIVE_VORBIS=1, ++MOZ_NATIVE_VORBIS= ) ++ ++if test -n "$MOZ_NATIVE_VORBIS"; then ++ PKG_CHECK_MODULES(MOZ_VORBIS, vorbis vorbisenc >= 1.3.4) ++fi ++ ++AC_SUBST(MOZ_NATIVE_VORBIS) ++AC_SUBST(MOZ_VORBIS_CFLAGS) ++AC_SUBST(MOZ_VORBIS_LIBS) ++ ++dnl ======================================================== + dnl = Disable Opus audio codec support + dnl ======================================================== + MOZ_ARG_DISABLE_BOOL(opus, +@@ -5238,6 +5196,25 @@ MOZ_ARG_DISABLE_BOOL(opus, + MOZ_OPUS=1) + + dnl ======================================================== ++dnl Check for libopus ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-opus, ++[ --with-system-opus Use system libopus (located with pkgconfig)], ++MOZ_NATIVE_OPUS=1, ++MOZ_NATIVE_OPUS= ) ++ ++if test -n "$MOZ_NATIVE_OPUS"; then ++ PKG_CHECK_MODULES(MOZ_OPUS, opus >= 1.1) ++else ++ MOZ_OPUS_CFLAGS='-I$(topsrcdir)/media/libopus/include' ++fi ++ ++AC_SUBST(MOZ_NATIVE_OPUS) ++AC_SUBST(MOZ_OPUS_CFLAGS) ++AC_SUBST(MOZ_OPUS_LIBS) ++ ++dnl ======================================================== + dnl = Disable VP8 decoder support + dnl ======================================================== + MOZ_ARG_DISABLE_BOOL(webm, +@@ -5606,43 +5583,60 @@ dnl = Enable GStreamer + dnl ======================================================== + if test "$OS_TARGET" = "Linux"; then + MOZ_GSTREAMER=1 ++ GST_API_VERSION=0.10 + fi + +-MOZ_ARG_ENABLE_BOOL(gstreamer, +-[ --enable-gstreamer Enable GStreamer support], +-MOZ_GSTREAMER=1, +-MOZ_GSTREAMER=) +- +-if test "$MOZ_GSTREAMER"; then +- # API version, eg 0.10, 1.0 etc ++MOZ_ARG_ENABLE_STRING(gstreamer, ++[ --enable-gstreamer[=0.10] Enable GStreamer support], ++[ MOZ_GSTREAMER=1 ++ # API version, eg 0.10, 1.0 etc ++ if test -z "$enableval" -o "$enableval" = "yes"; then + GST_API_VERSION=0.10 ++ elif test "$enableval" = "no"; then ++ MOZ_GSTREAMER= ++ else ++ GST_API_VERSION=$enableval ++ fi], ++) ++ ++if test -n "$MOZ_GSTREAMER"; then + # core/base release number +- GST_VERSION=0.10.25 ++ if test "$GST_API_VERSION" = "1.0"; then ++ GST_VERSION=1.0 ++ else ++ GST_VERSION=0.10.25 ++ fi ++ + PKG_CHECK_MODULES(GSTREAMER, + gstreamer-$GST_API_VERSION >= $GST_VERSION + gstreamer-app-$GST_API_VERSION +- gstreamer-plugins-base-$GST_API_VERSION, , +- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])) +- if test -n "$GSTREAMER_LIBS"; then +- _SAVE_LDFLAGS=$LDFLAGS +- LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" +- AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) +- if test -n "$_HAVE_LIBGSTVIDEO" ; then +- GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" +- else +- AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) +- fi +- LDFLAGS=$_SAVE_LDFLAGS ++ gstreamer-plugins-base-$GST_API_VERSION, ++ [_HAVE_GSTREAMER=1], ++ [_HAVE_GSTREAMER=]) ++ if test -z "$_HAVE_GSTREAMER"; then ++ AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) ++ fi ++ ++ _SAVE_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" ++ AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=) ++ if test -n "$_HAVE_LIBGSTVIDEO" ; then ++ GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION" + else +- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]) ++ AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.]) + fi ++ LDFLAGS=$_SAVE_LDFLAGS ++ ++ AC_SUBST(GSTREAMER_CFLAGS) ++ AC_SUBST(GSTREAMER_LIBS) + fi +-AC_SUBST(GSTREAMER_CFLAGS) +-AC_SUBST(GSTREAMER_LIBS) ++ + AC_SUBST(MOZ_GSTREAMER) ++AC_SUBST(GST_API_VERSION) + + if test -n "$MOZ_GSTREAMER"; then +- AC_DEFINE(MOZ_GSTREAMER) ++ AC_DEFINE(MOZ_GSTREAMER) ++ AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION") + fi + + +@@ -7424,7 +7418,10 @@ dnl ==================================== + dnl = Support for gcc stack unwinding (from gcc 3.3) + dnl ======================================================== + if test -z "$SKIP_LIBRARY_CHECKS"; then ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS + MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace)) ++ AC_LANG_RESTORE + fi + + dnl ======================================================== +@@ -7870,6 +7867,34 @@ if test "$USE_FC_FREETYPE"; then + fi + + dnl ======================================================== ++dnl Check for graphite2 and harfbuzz ++dnl ======================================================== ++ ++MOZ_ARG_WITH_BOOL(system-harfbuzz, ++[ --with-system-harfbuzz Use system harfbuzz (located with pkgconfig)], ++MOZ_NATIVE_HARFBUZZ=1, ++MOZ_NATIVE_HARFBUZZ= ) ++ ++if test -n "$MOZ_NATIVE_HARFBUZZ"; then ++ PKG_CHECK_MODULES(MOZ_HARFBUZZ, harfbuzz >= 0.9.25) ++fi ++AC_SUBST(MOZ_NATIVE_HARFBUZZ) ++AC_SUBST(MOZ_HARFBUZZ_CFLAGS) ++AC_SUBST(MOZ_HARFBUZZ_LIBS) ++ ++MOZ_ARG_WITH_BOOL(system-graphite2, ++[ --with-system-graphite2 Use system graphite2 (located with pkgconfig)], ++MOZ_NATIVE_GRAPHITE2=1, ++MOZ_NATIVE_GRAPHITE2= ) ++ ++if test -n "$MOZ_NATIVE_GRAPHITE2"; then ++ PKG_CHECK_MODULES(MOZ_GRAPHITE2, graphite2 >= 1.2.4) ++fi ++AC_SUBST(MOZ_NATIVE_GRAPHITE2) ++AC_SUBST(MOZ_GRAPHITE2_CFLAGS) ++AC_SUBST(MOZ_GRAPHITE2_LIBS) ++ ++dnl ======================================================== + dnl Check for pixman and cairo + dnl ======================================================== + +@@ -8118,7 +8143,7 @@ case "$OS_TARGET" in NECKO_WIFI=1 fi ;; @@ -140,14 +426,31 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $ NECKO_WIFI=1 ;; Linux) -@@ -9005,6 +9043,14 @@ if test -n "$INTEL_ARCHITECTURE"; then - fi - fi +@@ -8665,6 +8690,20 @@ AC_SUBST(MOZ_ENABLE_SZIP) + AC_SUBST(MOZ_SZIP_FLAGS) -+if test -n "$MOZ_LIBV4L2_LIBS"; then -+ EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1" + if test -n "$COMPILE_ENVIRONMENT"; then ++AC_MSG_CHECKING([for posix_fadvise]) ++AC_TRY_LINK([#define _XOPEN_SOURCE 600 ++ #include <fcntl.h>], ++ [posix_fadvise(0, 0, 0, 0);], ++ [ac_cv___posix_fadvise=true], ++ [ac_cv___posix_fadvise=false]) ++ ++if test "$ac_cv___posix_fadvise" = true ; then ++ AC_DEFINE(HAVE_POSIX_FADVISE) ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) +fi + + AC_MSG_CHECKING([for posix_fallocate]) + AC_TRY_LINK([#define _XOPEN_SOURCE 600 + #include <fcntl.h>], +@@ -8918,6 +8957,10 @@ if test -n "$INTEL_ARCHITECTURE"; then + fi + fi + +if test -n "$MOZ_LIBV4L2_LIBS"; then + EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1" +fi diff --git a/www/firefox/patches/patch-ao b/www/firefox/patches/patch-ao index 472f09c5760..f760db30271 100644 --- a/www/firefox/patches/patch-ao +++ b/www/firefox/patches/patch-ao @@ -1,16 +1,12 @@ -$NetBSD: patch-ao,v 1.12 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-ao,v 1.13 2014/03/20 21:02:00 ryoon Exp $ ---- toolkit/mozapps/installer/packager.mk.orig 2013-10-25 22:27:43.000000000 +0000 +--- toolkit/mozapps/installer/packager.mk.orig 2014-03-15 05:19:37.000000000 +0000 +++ toolkit/mozapps/installer/packager.mk -@@ -680,9 +680,9 @@ endif - (cd $(DIST)/$(MOZ_PKG_DIR) && $(TAR) --exclude=precomplete $(TAR_CREATE_FLAGS) - .) | \ - (cd $(DESTDIR)$(installdir) && tar -xf -) +@@ -775,7 +775,7 @@ endif $(NSINSTALL) -D $(DESTDIR)$(bindir) -- $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME) -- ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir) + $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME) + ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir) -ifdef INSTALL_SDK # Here comes the hard part -+ $(RM) -f $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME) -+ ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME) +ifeq ($(MOZ_APP_NAME),xulrunner) $(NSINSTALL) -D $(DESTDIR)$(includedir) (cd $(DIST)/include && $(TAR) $(TAR_CREATE_FLAGS) - .) | \ diff --git a/www/firefox/patches/patch-as b/www/firefox/patches/patch-as index 8d729285b4f..3da0733fcb3 100644 --- a/www/firefox/patches/patch-as +++ b/www/firefox/patches/patch-as @@ -1,27 +1,132 @@ -$NetBSD: patch-as,v 1.8 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-as,v 1.9 2014/03/20 21:02:00 ryoon Exp $ Treat DragonFly like FreeBSD. ---- js/src/configure.in.orig 2013-12-05 16:07:35.000000000 +0000 +--- js/src/configure.in.orig 2014-03-15 05:19:19.000000000 +0000 +++ js/src/configure.in -@@ -2290,6 +2290,7 @@ EOF - #pragma GCC visibility push(hidden) - #pragma GCC visibility push(default) - #include <string.h> -+#include <iterator> - #pragma GCC visibility pop +@@ -2148,116 +2148,13 @@ AC_LANG_CPLUSPLUS - __attribute__ ((visibility ("default"))) void Func() { -@@ -2298,7 +2299,7 @@ __attribute__ ((visibility ("default"))) - } - EOF - ac_cv_have_visibility_builtin_bug=no + MOZ_CXX11 + +-dnl Check for .hidden assembler directive and visibility attribute. +-dnl Borrowed from glibc configure.in ++dnl Setup default hidden visibility and wrapped system headers. + dnl =============================================================== + if test "$GNU_CC"; then +- AC_CACHE_CHECK(for visibility(hidden) attribute, +- ac_cv_visibility_hidden, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("hidden"))) = 1; +-EOF +- ac_cv_visibility_hidden=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_hidden=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_hidden" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility(default) attribute, +- ac_cv_visibility_default, +- [cat > conftest.c <<EOF +- int foo __attribute__ ((visibility ("default"))) = 1; +-EOF +- ac_cv_visibility_default=no +- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then +- ac_cv_visibility_default=yes +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_default" = "yes"; then +- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) +- +- AC_CACHE_CHECK(for visibility pragma support, +- ac_cv_visibility_pragma, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +- int foo_hidden = 1; +-#pragma GCC visibility push(default) +- int foo_default = 1; +-EOF +- ac_cv_visibility_pragma=no +- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then +- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then +- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then +- ac_cv_visibility_pragma=yes +- fi +- fi +- fi +- rm -f conftest.[cs] +- ]) +- if test "$ac_cv_visibility_pragma" = "yes"; then +- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905), +- ac_cv_have_visibility_class_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-struct __attribute__ ((visibility ("default"))) TestStruct { +- static void Init(); +-}; +-__attribute__ ((visibility ("default"))) void TestFunc() { +- TestStruct::Init(); +-} +-EOF +- ac_cv_have_visibility_class_bug=no +- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then +- ac_cv_have_visibility_class_bug=yes +- else +- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then +- ac_cv_have_visibility_class_bug=yes +- fi +- fi +- rm -rf conftest.{c,S} +- ]) +- +- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297), +- ac_cv_have_visibility_builtin_bug, +- [cat > conftest.c <<EOF +-#pragma GCC visibility push(hidden) +-#pragma GCC visibility push(default) +-#include <string.h> +-#pragma GCC visibility pop +- +-__attribute__ ((visibility ("default"))) void Func() { +- char c[[100]]; +- memset(c, 0, sizeof(c)); +-} +-EOF +- ac_cv_have_visibility_builtin_bug=no - if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then -+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then - ac_cv_have_visibility_builtin_bug=yes - else - if test `grep -c "@PLT" conftest.S` = 0; then -@@ -2515,7 +2516,7 @@ then +- ac_cv_have_visibility_builtin_bug=yes +- else +- if test `grep -c "@PLT" conftest.S` = 0; then +- ac_cv_visibility_builtin_bug=yes +- fi +- fi +- rm -f conftest.{c,S} +- ]) +- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ +- "$ac_cv_have_visibility_class_bug" = "no"; then +- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' +- WRAP_SYSTEM_INCLUDES=1 +- else +- VISIBILITY_FLAGS='-fvisibility=hidden' +- fi # have visibility pragma bug +- fi # have visibility pragma +- fi # have visibility(default) attribute +- fi # have visibility(hidden) attribute ++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) ++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE) ++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' ++ WRAP_SYSTEM_INCLUDES=1 + fi # GNU_CC + + # visibility hidden flag for Sun Studio on Solaris +@@ -2456,7 +2353,7 @@ then fi case "$target" in @@ -30,33 +135,7 @@ Treat DragonFly like FreeBSD. AC_DEFINE(_REENTRANT) AC_DEFINE(_THREAD_SAFE) dnl -pthread links in -lpthread, so don't specify it explicitly. -@@ -2600,14 +2601,22 @@ fi - AC_CACHE_CHECK( - [for res_ninit()], - ac_cv_func_res_ninit, -- [AC_TRY_LINK([ -+ [AC_TRY_RUN([ - #ifdef linux - #define _BSD_SOURCE 1 - #endif -+ #ifdef __NetBSD__ -+ #error use of global _res variable in threaded programs is not portable -+ #endif -+ #include <sys/types.h> -+ #include <netinet/in.h> -+ #include <arpa/nameser.h> - #include <resolv.h> -- ], -- [int foo = res_ninit(&_res);], -+ int main(int argc, char **argv){ -+ int foo = res_ninit(&_res); -+ }], - [ac_cv_func_res_ninit=yes], -+ [ac_cv_func_res_ninit=no], - [ac_cv_func_res_ninit=no]) - ]) - -@@ -3316,7 +3325,7 @@ if test "$MOZ_MEMORY"; then +@@ -3270,7 +3167,7 @@ if test "$MOZ_MEMORY"; then *-darwin*) AC_DEFINE(MOZ_MEMORY_DARWIN) ;; @@ -65,7 +144,39 @@ Treat DragonFly like FreeBSD. AC_DEFINE(MOZ_MEMORY_BSD) ;; *-android*|*-linuxandroid*) -@@ -4339,6 +4348,16 @@ fi +@@ -3632,7 +3529,10 @@ dnl ==================================== + dnl = Support for gcc stack unwinding (from gcc 3.3) + dnl ======================================================== + if test -z "$SKIP_LIBRARY_CHECKS"; then ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS + MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace)) ++ AC_LANG_RESTORE + fi + + dnl ======================================================== +@@ -4086,6 +3986,20 @@ AC_SUBST(CXX_VERSION) + AC_SUBST(MSMANIFEST_TOOL) + AC_SUBST(MOZ_LINKER) + ++AC_MSG_CHECKING([for posix_fadvise]) ++AC_TRY_LINK([#define _XOPEN_SOURCE 600 ++ #include <fcntl.h>], ++ [posix_fadvise(0, 0, 0, 0);], ++ [ac_cv___posix_fadvise=true], ++ [ac_cv___posix_fadvise=false]) ++ ++if test "$ac_cv___posix_fadvise" = true ; then ++ AC_DEFINE(HAVE_POSIX_FADVISE) ++ AC_MSG_RESULT(yes) ++else ++ AC_MSG_RESULT(no) ++fi ++ + AC_MSG_CHECKING([for posix_fallocate]) + AC_TRY_LINK([#define _XOPEN_SOURCE 600 + #include <fcntl.h>], +@@ -4436,6 +4350,16 @@ fi dnl ======================================================== dnl JavaScript shell dnl ======================================================== diff --git a/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp b/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp new file mode 100644 index 00000000000..cfe7efb6e03 --- /dev/null +++ b/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp @@ -0,0 +1,12 @@ +$NetBSD: patch-browser_app_nsBrowserApp.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- browser/app/nsBrowserApp.cpp.orig 2014-03-15 05:19:07.000000000 +0000 ++++ browser/app/nsBrowserApp.cpp +@@ -586,6 +586,7 @@ int main(int argc, char* argv[]) + TriggerQuirks(); + #endif + ++ setenv("MOZ_PLUGIN_PATH", "%%LOCALBASE%%/lib/browser_plugins/symlinks/gecko", 0); + int gotCounters; + #if defined(XP_UNIX) + struct rusage initialRUsage; diff --git a/www/firefox/patches/patch-browser_installer_package-manifest.in b/www/firefox/patches/patch-browser_installer_package-manifest.in index 3ece8451a17..666d95fab8d 100644 --- a/www/firefox/patches/patch-browser_installer_package-manifest.in +++ b/www/firefox/patches/patch-browser_installer_package-manifest.in @@ -1,11 +1,11 @@ -$NetBSD: patch-browser_installer_package-manifest.in,v 1.3 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-browser_installer_package-manifest.in,v 1.4 2014/03/20 21:02:00 ryoon Exp $ Limit SPARC bits to just SPARC (untested, but fixes x86). ---- browser/installer/package-manifest.in.orig 2013-06-18 11:01:12.000000000 +0000 +--- browser/installer/package-manifest.in.orig 2014-03-15 05:19:09.000000000 +0000 +++ browser/installer/package-manifest.in -@@ -690,7 +690,7 @@ - @BINPATH@/components/pippki.xpt +@@ -732,7 +732,7 @@ + #endif ; for Solaris SPARC -#ifdef SOLARIS diff --git a/www/firefox/patches/patch-browser_themes_shared_devtools_common.css b/www/firefox/patches/patch-browser_themes_shared_devtools_common.css new file mode 100644 index 00000000000..7e1a7176526 --- /dev/null +++ b/www/firefox/patches/patch-browser_themes_shared_devtools_common.css @@ -0,0 +1,32 @@ +$NetBSD: patch-browser_themes_shared_devtools_common.css,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- browser/themes/shared/devtools/common.css.orig 2014-03-15 05:19:09.000000000 +0000 ++++ browser/themes/shared/devtools/common.css +@@ -11,13 +11,13 @@ + .devtools-monospace { + %ifdef XP_MACOSX + font-family: Menlo, monospace; +-%endif +-%ifdef XP_LINUX ++%elifdef XP_WIN ++ font-family: Consolas, monospace; ++%else + font-family: monospace; +- font-size: 80%; + %endif +-%ifdef XP_WIN +- font-family: Consolas, monospace; ++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT) ++ font-size: 80%; + %endif + } + +@@ -62,7 +62,7 @@ + background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%)); + border-radius: 3px; + overflow-x: hidden; +-%ifdef XP_LINUX ++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT) + max-height: 32rem; + %else + max-height: 40rem; diff --git a/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css b/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css new file mode 100644 index 00000000000..bde96910327 --- /dev/null +++ b/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css @@ -0,0 +1,13 @@ +$NetBSD: patch-browser_themes_shared_devtools_highlighter.inc.css,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- browser/themes/shared/devtools/highlighter.inc.css.orig 2014-03-15 05:19:09.000000000 +0000 ++++ browser/themes/shared/devtools/highlighter.inc.css +@@ -54,7 +54,7 @@ html|*.highlighter-nodeinfobar-pseudo-cl + padding: 0; + width: 26px; + min-height: 26px; +-%ifndef XP_LINUX ++%if !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_QT) + background-color: transparent; + %endif + } diff --git a/www/firefox/patches/patch-build_pgo_profileserver.py b/www/firefox/patches/patch-build_pgo_profileserver.py new file mode 100644 index 00000000000..389a0641bda --- /dev/null +++ b/www/firefox/patches/patch-build_pgo_profileserver.py @@ -0,0 +1,13 @@ +$NetBSD: patch-build_pgo_profileserver.py,v 1.3 2014/03/20 21:02:00 ryoon Exp $ + +--- build/pgo/profileserver.py.orig 2014-03-15 05:19:09.000000000 +0000 ++++ build/pgo/profileserver.py +@@ -59,7 +59,7 @@ if __name__ == '__main__': + env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog) + print "jarlog: %s" % env["MOZ_JAR_LOG_FILE"] + +- cmdargs = ["http://localhost:%d/index.html" % PORT] ++ cmdargs = ["http://127.0.0.1:%d/index.html" % PORT] + runner = FirefoxRunner(profile=profile, + binary=build.get_binary_path(where="staged-package"), + cmdargs=cmdargs, diff --git a/www/firefox/patches/patch-config_Makefile.in b/www/firefox/patches/patch-config_Makefile.in new file mode 100644 index 00000000000..b6fe6db4832 --- /dev/null +++ b/www/firefox/patches/patch-config_Makefile.in @@ -0,0 +1,16 @@ +$NetBSD: patch-config_Makefile.in,v 1.3 2014/03/20 21:02:00 ryoon Exp $ + +--- config/Makefile.in.orig 2014-03-15 05:19:09.000000000 +0000 ++++ config/Makefile.in +@@ -73,6 +73,11 @@ export:: $(export-preqs) + -DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \ + -DMOZ_NATIVE_LIBVPX=$(MOZ_NATIVE_LIBVPX) \ + -DMOZ_NATIVE_ICU=$(MOZ_NATIVE_ICU) \ ++ -DMOZ_NATIVE_GRAPHITE2=$(MOZ_NATIVE_GRAPHITE2) \ ++ -DMOZ_NATIVE_HARFBUZZ=$(MOZ_NATIVE_HARFBUZZ) \ ++ -DMOZ_NATIVE_OGG=$(MOZ_NATIVE_OGG) \ ++ -DMOZ_NATIVE_VORBIS=$(MOZ_NATIVE_VORBIS) \ ++ -DMOZ_NATIVE_OPUS=$(MOZ_NATIVE_OPUS) \ + $(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers + $(INSTALL) system_wrappers $(DIST) + diff --git a/www/firefox/patches/patch-config_external_moz.build b/www/firefox/patches/patch-config_external_moz.build new file mode 100644 index 00000000000..4199ee392ce --- /dev/null +++ b/www/firefox/patches/patch-config_external_moz.build @@ -0,0 +1,31 @@ +$NetBSD: patch-config_external_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- config/external/moz.build.orig 2014-03-15 05:19:09.000000000 +0000 ++++ config/external/moz.build +@@ -15,13 +15,13 @@ if CONFIG['MOZ_UPDATER']: + if not CONFIG['MOZ_NATIVE_BZ2']: + external_dirs += ['modules/libbz2'] + +-if CONFIG['MOZ_VORBIS']: ++if CONFIG['MOZ_VORBIS'] and not CONFIG['MOZ_NATIVE_VORBIS']: + external_dirs += ['media/libvorbis'] + + if CONFIG['MOZ_TREMOR']: + external_dirs += ['media/libtremor'] + +-if CONFIG['MOZ_OPUS']: ++if CONFIG['MOZ_OPUS'] and not CONFIG['MOZ_NATIVE_OPUS']: + external_dirs += ['media/libopus'] + + if CONFIG['MOZ_WEBM']: +@@ -31,7 +31,9 @@ if CONFIG['MOZ_VP8'] and not CONFIG['MOZ + external_dirs += ['media/libvpx'] + + if CONFIG['MOZ_OGG']: +- external_dirs += ['media/libogg', 'media/libtheora'] ++ if not CONFIG['MOZ_NATIVE_OGG']: ++ external_dirs += ['media/libogg'] ++ external_dirs += ['media/libtheora'] + + if not CONFIG['MOZ_NATIVE_PNG']: + external_dirs += ['media/libpng'] diff --git a/www/firefox/patches/patch-config_system-headers b/www/firefox/patches/patch-config_system-headers index baf1c19310d..be8339eb3a4 100644 --- a/www/firefox/patches/patch-config_system-headers +++ b/www/firefox/patches/patch-config_system-headers @@ -1,9 +1,33 @@ -$NetBSD: patch-config_system-headers,v 1.6 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-config_system-headers,v 1.7 2014/03/20 21:02:00 ryoon Exp $ ---- config/system-headers.orig 2013-12-05 16:07:23.000000000 +0000 +--- config/system-headers.orig 2014-03-15 05:19:09.000000000 +0000 +++ config/system-headers -@@ -1144,3 +1144,4 @@ unicode/unum.h +@@ -1144,4 +1144,28 @@ unicode/unum.h unicode/ustring.h unicode/utypes.h #endif -+libutil.h ++cairo-qt.h ++#if MOZ_NATIVE_GRAPHITE2==1 ++unwind.h ++graphite2/Font.h ++graphite2/Segment.h ++#endif ++#if MOZ_NATIVE_HARFBUZZ==1 ++harfbuzz/hb-ot.h ++harfbuzz/hb.h ++#endif ++#if MOZ_NATIVE_OGG==1 ++ogg/ogg.h ++ogg/os_types.h ++#endif ++#if MOZ_NATIVE_VORBIS==1 ++vorbis/codec.h ++vorbis/vorbisenc.h ++#endif ++#if MOZ_NATIVE_OPUS==1 ++opus.h ++opus_multistream.h ++opus/opus.h ++opus/opus_multistream.h ++#endif + libutil.h diff --git a/www/firefox/patches/patch-content_base_src_Makefile.in b/www/firefox/patches/patch-content_base_src_Makefile.in new file mode 100644 index 00000000000..dee5f3485e6 --- /dev/null +++ b/www/firefox/patches/patch-content_base_src_Makefile.in @@ -0,0 +1,15 @@ +$NetBSD: patch-content_base_src_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/base/src/Makefile.in.orig 2014-03-15 05:19:10.000000000 +0000 ++++ content/base/src/Makefile.in +@@ -5,6 +5,10 @@ + + include $(topsrcdir)/config/rules.mk + ++ifdef MOZ_NATIVE_HARFBUZZ ++nsContentUtils.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + # gcc requires -msse2 for this file since it uses SSE2 intrinsics. (See bug + # 585538 comment 12.) + ifneq (,$(INTEL_ARCHITECTURE)) diff --git a/www/firefox/patches/patch-content_media_Makefile.in b/www/firefox/patches/patch-content_media_Makefile.in new file mode 100644 index 00000000000..281c780283c --- /dev/null +++ b/www/firefox/patches/patch-content_media_Makefile.in @@ -0,0 +1,21 @@ +$NetBSD: patch-content_media_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/Makefile.in.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/Makefile.in +@@ -7,4 +7,16 @@ include $(topsrcdir)/config/rules.mk + CFLAGS += $(GSTREAMER_CFLAGS) + CXXFLAGS += $(GSTREAMER_CFLAGS) + ++ifdef MOZ_NATIVE_OGG ++CXXFLAGS += $(MOZ_OGG_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_VORBIS ++CXXFLAGS += $(MOZ_VORBIS_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_OPUS ++CXXFLAGS += $(MOZ_OPUS_CFLAGS) ++endif ++ + AudioNodeEngineNEON.$(OBJ_SUFFIX): CXXFLAGS += -mfpu=neon diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp new file mode 100644 index 00000000000..ab175dc7d15 --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp @@ -0,0 +1,203 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerAllocator.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerAllocator.cpp.orig 2014-03-20 11:09:40.000000000 +0000 ++++ content/media/gstreamer/GStreamerAllocator.cpp +@@ -0,0 +1,198 @@ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "GStreamerAllocator.h" ++ ++#include <gst/video/video.h> ++#include <gst/video/gstvideometa.h> ++ ++#include "GStreamerLoader.h" ++ ++using namespace mozilla::layers; ++ ++namespace mozilla { ++ ++typedef struct ++{ ++ GstAllocator parent; ++ GStreamerReader *reader; ++} MozGfxMemoryAllocator; ++ ++typedef struct ++{ ++ GstAllocatorClass parent; ++} MozGfxMemoryAllocatorClass; ++ ++typedef struct ++{ ++ GstMemory memory; ++ PlanarYCbCrImage* image; ++ guint8* data; ++} MozGfxMemory; ++ ++typedef struct ++{ ++ GstMeta meta; ++} MozGfxMeta; ++ ++typedef struct ++{ ++ GstVideoBufferPoolClass parent_class; ++} MozGfxBufferPoolClass; ++ ++typedef struct ++{ ++ GstVideoBufferPool pool; ++} MozGfxBufferPool; ++ ++G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR); ++G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL); ++ ++void ++moz_gfx_memory_reset(MozGfxMemory *mem) ++{ ++ if (mem->image) ++ mem->image->Release(); ++ ++ ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer(); ++ ImageFormat format = PLANAR_YCBCR; ++ mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); ++ mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size); ++} ++ ++static GstMemory* ++moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize, ++ GstAllocationParams* aParams) ++{ ++ MozGfxMemory* mem = g_slice_new (MozGfxMemory); ++ gsize maxsize = aSize + aParams->prefix + aParams->padding; ++ gst_memory_init(GST_MEMORY_CAST (mem), ++ (GstMemoryFlags)aParams->flags, ++ aAllocator, NULL, maxsize, aParams->align, ++ aParams->prefix, aSize); ++ mem->image = NULL; ++ moz_gfx_memory_reset(mem); ++ ++ return (GstMemory *) mem; ++} ++ ++static void ++moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem) ++{ ++ MozGfxMemory *mem = (MozGfxMemory *) gmem; ++ ++ if (mem->memory.parent) ++ goto sub_mem; ++ ++ if (mem->image) ++ mem->image->Release(); ++ ++sub_mem: ++ g_slice_free (MozGfxMemory, mem); ++} ++ ++static gpointer ++moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags) ++{ ++ // check that the allocation didn't fail ++ if (mem->data == nullptr) ++ return nullptr; ++ ++ return mem->data + mem->memory.offset; ++} ++ ++static gboolean ++moz_gfx_memory_unmap (MozGfxMemory * mem) ++{ ++ return TRUE; ++} ++ ++static MozGfxMemory * ++moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) ++{ ++ MozGfxMemory *sub; ++ GstMemory *parent; ++ ++ /* find the real parent */ ++ if ((parent = mem->memory.parent) == NULL) ++ parent = (GstMemory *) mem; ++ ++ if (size == (gsize) -1) ++ size = mem->memory.size - offset; ++ ++ /* the shared memory is always readonly */ ++ sub = g_slice_new (MozGfxMemory); ++ ++ gst_memory_init (GST_MEMORY_CAST (sub), ++ (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), ++ mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, ++ mem->memory.offset + offset, size); ++ ++ sub->image = mem->image; ++ sub->data = mem->data; ++ ++ return sub; ++} ++ ++static void ++moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass) ++{ ++ GstAllocatorClass *allocator_class; ++ ++ allocator_class = (GstAllocatorClass *) klass; ++ ++ allocator_class->alloc = moz_gfx_memory_allocator_alloc; ++ allocator_class->free = moz_gfx_memory_allocator_free; ++} ++ ++static void ++moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator) ++{ ++ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); ++ ++ alloc->mem_type = "moz-gfx-image"; ++ alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map; ++ alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap; ++ alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share; ++ /* fallback copy and is_span */ ++} ++ ++void ++moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader) ++{ ++ MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator; ++ allocator->reader = aReader; ++} ++ ++nsRefPtr<PlanarYCbCrImage> ++moz_gfx_memory_get_image(GstMemory *aMemory) ++{ ++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image"); ++ ++ return ((MozGfxMemory *) aMemory)->image; ++} ++ ++void ++moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) ++{ ++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); ++ ++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); ++ moz_gfx_memory_reset((MozGfxMemory *) mem); ++ GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); ++} ++ ++static void ++moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass) ++{ ++ GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass; ++ pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer; ++} ++ ++static void ++moz_gfx_buffer_pool_init (MozGfxBufferPool * pool) ++{ ++} ++ ++} // namespace mozilla diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h new file mode 100644 index 00000000000..a8b15f3a754 --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h @@ -0,0 +1,30 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerAllocator.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerAllocator.h.orig 2014-03-20 11:09:40.000000000 +0000 ++++ content/media/gstreamer/GStreamerAllocator.h +@@ -0,0 +1,25 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this file, ++ * You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#if !defined(GStreamerAllocator_h_) ++#define GStreamerAllocator_h_ ++ ++#include "GStreamerReader.h" ++ ++#define GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR (moz_gfx_memory_allocator_get_type()) ++#define GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR)) ++#define GST_TYPE_MOZ_GFX_BUFFER_POOL (moz_gfx_buffer_pool_get_type()) ++#define GST_IS_MOZ_GFX_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_BUFFER_POOL)) ++ ++namespace mozilla { ++ ++GType moz_gfx_memory_allocator_get_type(); ++void moz_gfx_memory_allocator_set_reader(GstAllocator *aAllocator, GStreamerReader* aReader); ++nsRefPtr<layers::PlanarYCbCrImage> moz_gfx_memory_get_image(GstMemory *aMemory); ++ ++GType moz_gfx_buffer_pool_get_type(); ++ ++} // namespace mozilla ++ ++#endif diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp new file mode 100644 index 00000000000..2886bda65fa --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp @@ -0,0 +1,29 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerFormatHelper.cpp,v 1.3 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerFormatHelper.cpp.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerFormatHelper.cpp +@@ -294,12 +294,23 @@ bool GStreamerFormatHelper::CanHandleCod + GList* GStreamerFormatHelper::GetFactories() { + NS_ASSERTION(sLoadOK, "GStreamer library not linked"); + +- uint32_t cookie = gst_default_registry_get_feature_list_cookie (); ++#if GST_VERSION_MAJOR >= 1 ++ uint32_t cookie = gst_registry_get_feature_list_cookie(gst_registry_get()); ++#else ++ uint32_t cookie = gst_default_registry_get_feature_list_cookie(); ++#endif + if (cookie != mCookie) { + g_list_free(mFactories); ++#if GST_VERSION_MAJOR >= 1 ++ mFactories = ++ gst_registry_feature_filter(gst_registry_get(), ++ (GstPluginFeatureFilter)FactoryFilter, ++ false, nullptr); ++#else + mFactories = + gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter, + false, nullptr); ++#endif + mCookie = cookie; + } + diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h new file mode 100644 index 00000000000..c697e0143a6 --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h @@ -0,0 +1,168 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerFunctionList.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerFunctionList.h.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerFunctionList.h +@@ -9,7 +9,6 @@ + * List of symbol names we need to dlsym from the gstreamer library. + */ + GST_FUNC(LIBGSTAPP, gst_app_sink_get_type) +-GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) + GST_FUNC(LIBGSTAPP, gst_app_sink_set_callbacks) + GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream) + GST_FUNC(LIBGSTAPP, gst_app_src_get_size) +@@ -22,10 +21,8 @@ GST_FUNC(LIBGSTAPP, gst_app_src_set_stre + GST_FUNC(LIBGSTREAMER, gst_bin_get_by_name) + GST_FUNC(LIBGSTREAMER, gst_bin_get_type) + GST_FUNC(LIBGSTREAMER, gst_bin_iterate_recurse) +-GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) + GST_FUNC(LIBGSTREAMER, gst_buffer_get_type) + GST_FUNC(LIBGSTREAMER, gst_buffer_new) +-GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) + GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler) + GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered) + GST_FUNC(LIBGSTREAMER, gst_caps_append) +@@ -37,47 +34,37 @@ GST_FUNC(LIBGSTREAMER, gst_caps_new_any) + GST_FUNC(LIBGSTREAMER, gst_caps_new_empty) + GST_FUNC(LIBGSTREAMER, gst_caps_new_full) + GST_FUNC(LIBGSTREAMER, gst_caps_new_simple) +-GST_FUNC(LIBGSTREAMER, gst_caps_unref) +-GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) ++GST_FUNC(LIBGSTREAMER, gst_caps_set_simple) + GST_FUNC(LIBGSTREAMER, gst_element_factory_get_static_pad_templates) + GST_FUNC(LIBGSTREAMER, gst_element_factory_get_type) + GST_FUNC(LIBGSTREAMER, gst_element_factory_make) + GST_FUNC(LIBGSTREAMER, gst_element_get_factory) +-GST_FUNC(LIBGSTREAMER, gst_element_get_pad) ++GST_FUNC(LIBGSTREAMER, gst_element_get_static_pad) + GST_FUNC(LIBGSTREAMER, gst_element_get_type) + GST_FUNC(LIBGSTREAMER, gst_element_query_convert) + GST_FUNC(LIBGSTREAMER, gst_element_query_duration) + GST_FUNC(LIBGSTREAMER, gst_element_seek_simple) + GST_FUNC(LIBGSTREAMER, gst_element_set_state) +-GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) + GST_FUNC(LIBGSTREAMER, gst_flow_get_name) + GST_FUNC(LIBGSTREAMER, gst_init) + GST_FUNC(LIBGSTREAMER, gst_init_check) + GST_FUNC(LIBGSTREAMER, gst_iterator_next) + GST_FUNC(LIBGSTREAMER, gst_message_parse_error) + GST_FUNC(LIBGSTREAMER, gst_message_type_get_name) +-GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) +-GST_FUNC(LIBGSTREAMER, gst_mini_object_new) + GST_FUNC(LIBGSTREAMER, gst_mini_object_ref) + GST_FUNC(LIBGSTREAMER, gst_mini_object_unref) + GST_FUNC(LIBGSTREAMER, gst_object_get_name) + GST_FUNC(LIBGSTREAMER, gst_object_get_parent) + GST_FUNC(LIBGSTREAMER, gst_object_unref) +-GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) +-GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) + GST_FUNC(LIBGSTREAMER, gst_pad_get_element_private) +-GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) +-GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) + GST_FUNC(LIBGSTREAMER, gst_pad_set_element_private) + GST_FUNC(LIBGSTREAMER, gst_parse_bin_from_description) + GST_FUNC(LIBGSTREAMER, gst_pipeline_get_bus) + GST_FUNC(LIBGSTREAMER, gst_pipeline_get_type) + GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_rank) + GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter) +-GST_FUNC(LIBGSTREAMER, gst_registry_get_default) + GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie) + GST_FUNC(LIBGSTREAMER, gst_segment_init) +-GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) + GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time) + GST_FUNC(LIBGSTREAMER, gst_static_caps_get) + GST_FUNC(LIBGSTREAMER, gst_structure_copy) +@@ -86,11 +73,82 @@ GST_FUNC(LIBGSTREAMER, gst_structure_get + GST_FUNC(LIBGSTREAMER, gst_structure_get_value) + GST_FUNC(LIBGSTREAMER, gst_structure_new) + GST_FUNC(LIBGSTREAMER, gst_util_uint64_scale) ++ ++#if GST_VERSION_MAJOR == 0 ++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer) ++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata) ++GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc) ++GST_FUNC(LIBGSTREAMER, gst_caps_unref) ++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass) ++GST_FUNC(LIBGSTREAMER, gst_element_get_pad) ++GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment) ++GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type) ++GST_FUNC(LIBGSTREAMER, gst_mini_object_new) ++GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe) ++GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer) ++GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps) ++GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function) ++GST_FUNC(LIBGSTREAMER, gst_registry_get_default) ++GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_height) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_offset) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_width) ++GST_FUNC(LIBGSTVIDEO, gst_video_format_get_pixel_stride) + GST_FUNC(LIBGSTVIDEO, gst_video_format_get_row_stride) + GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps) ++#else ++ ++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_sample) ++GST_FUNC(LIBGSTREAMER, _gst_caps_any) ++GST_FUNC(LIBGSTREAMER, gst_allocator_get_type) ++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_into) ++GST_FUNC(LIBGSTREAMER, gst_buffer_extract) ++GST_FUNC(LIBGSTREAMER, gst_buffer_get_meta) ++GST_FUNC(LIBGSTREAMER, gst_buffer_get_size) ++GST_FUNC(LIBGSTREAMER, gst_buffer_map) ++GST_FUNC(LIBGSTREAMER, gst_buffer_new_allocate) ++GST_FUNC(LIBGSTREAMER, gst_buffer_n_memory) ++GST_FUNC(LIBGSTREAMER, gst_buffer_peek_memory) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_acquire_buffer) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_allocator) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_params) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_config) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_type) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_is_active) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_active) ++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_config) ++GST_FUNC(LIBGSTREAMER, gst_buffer_set_size) ++GST_FUNC(LIBGSTREAMER, gst_buffer_unmap) ++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_metadata) ++GST_FUNC(LIBGSTREAMER, gst_event_parse_segment) ++GST_FUNC(LIBGSTREAMER, gst_memory_init) ++GST_FUNC(LIBGSTREAMER, gst_memory_map) ++GST_FUNC(LIBGSTREAMER, gst_memory_unmap) ++GST_FUNC(LIBGSTREAMER, gst_object_get_type) ++GST_FUNC(LIBGSTREAMER, gst_pad_add_probe) ++GST_FUNC(LIBGSTREAMER, gst_pad_get_current_caps) ++GST_FUNC(LIBGSTREAMER, gst_pad_probe_info_get_query) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_meta) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_param) ++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_pool) ++GST_FUNC(LIBGSTREAMER, gst_query_parse_allocation) ++GST_FUNC(LIBGSTREAMER, gst_registry_get) ++GST_FUNC(LIBGSTREAMER, gst_sample_get_buffer) ++GST_FUNC(LIBGSTREAMER, gst_segment_copy_into) ++GST_FUNC(LIBGSTREAMER, gst_structure_free) ++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_config_get_video_alignment) ++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_has_option) ++GST_FUNC(LIBGSTVIDEO, gst_video_buffer_pool_get_type) ++GST_FUNC(LIBGSTVIDEO, gst_video_frame_map) ++GST_FUNC(LIBGSTVIDEO, gst_video_frame_unmap) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_align) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_from_caps) ++GST_FUNC(LIBGSTVIDEO, gst_video_info_init) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_api_get_type) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_map) ++GST_FUNC(LIBGSTVIDEO, gst_video_meta_unmap) ++ ++#endif + + /* + * Functions that have been defined in the header file. We replace them so that +@@ -100,6 +158,11 @@ GST_FUNC(LIBGSTVIDEO, gst_video_format_p + REPLACE_FUNC(gst_buffer_ref); + REPLACE_FUNC(gst_buffer_unref); + REPLACE_FUNC(gst_message_unref); ++ ++#if GST_VERSION_MAJOR == 1 ++REPLACE_FUNC(gst_caps_unref); ++REPLACE_FUNC(gst_sample_unref); ++#endif + #endif + + #endif // !defined(__APPLE__) diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp new file mode 100644 index 00000000000..92451a214dc --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp @@ -0,0 +1,97 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerLoader.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerLoader.cpp.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerLoader.cpp +@@ -6,13 +6,21 @@ + #include <dlfcn.h> + #include <stdio.h> + +-#include "GStreamerLoader.h" ++#include "nsDebug.h" + #include "mozilla/NullPtr.h" + ++#include "GStreamerLoader.h" ++ + #define LIBGSTREAMER 0 + #define LIBGSTAPP 1 + #define LIBGSTVIDEO 2 + ++#ifdef __OpenBSD__ ++#define LIB_GST_SUFFIX ".so" ++#else ++#define LIB_GST_SUFFIX ".so.0" ++#endif ++ + namespace mozilla { + + /* +@@ -32,6 +40,11 @@ namespace mozilla { + GstBuffer * gst_buffer_ref_impl(GstBuffer *buf); + void gst_buffer_unref_impl(GstBuffer *buf); + void gst_message_unref_impl(GstMessage *msg); ++void gst_caps_unref_impl(GstCaps *caps); ++ ++#if GST_VERSION_MAJOR == 1 ++void gst_sample_unref_impl(GstSample *sample); ++#endif + + bool + load_gstreamer() +@@ -58,32 +71,25 @@ load_gstreamer() + if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) { + gstreamerLib = RTLD_DEFAULT; + } else { +-#ifdef __OpenBSD__ +- gstreamerLib = dlopen("libgstreamer-0.10.so", RTLD_NOW | RTLD_LOCAL); +-#else +- gstreamerLib = dlopen("libgstreamer-0.10.so.0", RTLD_NOW | RTLD_LOCAL); +-#endif ++ gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL); + } + +- void *handles[] = { ++ void *handles[3] = { + gstreamerLib, +-#ifdef __OpenBSD__ +- dlopen("libgstapp-0.10.so", RTLD_NOW | RTLD_LOCAL), +- dlopen("libgstvideo-0.10.so", RTLD_NOW | RTLD_LOCAL) +-#else +- dlopen("libgstapp-0.10.so.0", RTLD_NOW | RTLD_LOCAL), +- dlopen("libgstvideo-0.10.so.0", RTLD_NOW | RTLD_LOCAL) +-#endif ++ dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL), ++ dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL) + }; + + for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) { + if (!handles[i]) { ++ NS_WARNING("Couldn't link gstreamer libraries"); + goto fail; + } + } + + #define GST_FUNC(lib, symbol) \ + if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \ ++ NS_WARNING("Couldn't link symbol " #symbol); \ + goto fail; \ + } + #define REPLACE_FUNC(symbol) symbol = symbol##_impl; +@@ -123,4 +129,18 @@ gst_message_unref_impl(GstMessage *msg) + gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg)); + } + ++#if GST_VERSION_MAJOR == 1 ++void ++gst_sample_unref_impl(GstSample *sample) ++{ ++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample)); ++} ++#endif ++ ++void ++gst_caps_unref_impl(GstCaps *caps) ++{ ++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps)); ++} ++ + } diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h new file mode 100644 index 00000000000..8a0d20a1be9 --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h @@ -0,0 +1,24 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerLoader.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerLoader.h.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerLoader.h +@@ -22,6 +22,11 @@ + #include <gst/video/video.h> + #pragma GCC diagnostic pop + ++#if GST_VERSION_MAJOR == 1 ++#include <gst/video/gstvideometa.h> ++#include <gst/video/gstvideopool.h> ++#endif ++ + namespace mozilla { + + /* +@@ -42,4 +47,7 @@ bool load_gstreamer(); + + } + ++#undef GST_CAPS_ANY ++#define GST_CAPS_ANY (*_gst_caps_any) ++ + #endif // GStreamerLoader_h_ diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp new file mode 100644 index 00000000000..b126ae850bf --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp @@ -0,0 +1,208 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerReader-0.10.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerReader-0.10.cpp.orig 2014-03-20 11:09:40.000000000 +0000 ++++ content/media/gstreamer/GStreamerReader-0.10.cpp +@@ -0,0 +1,203 @@ ++#include "nsError.h" ++#include "MediaDecoderStateMachine.h" ++#include "AbstractMediaDecoder.h" ++#include "MediaResource.h" ++#include "GStreamerReader.h" ++#include "GStreamerMozVideoBuffer.h" ++#include "GStreamerFormatHelper.h" ++#include "VideoUtils.h" ++#include "mozilla/dom/TimeRanges.h" ++#include "mozilla/Preferences.h" ++ ++using namespace mozilla; ++using mozilla::layers::PlanarYCbCrImage; ++using mozilla::layers::ImageContainer; ++ ++GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); ++ return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf); ++} ++ ++GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf) ++{ ++ nsRefPtr<PlanarYCbCrImage> image; ++ return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image); ++} ++ ++GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad, ++ guint64 aOffset, ++ guint aSize, ++ GstCaps* aCaps, ++ GstBuffer** aBuf, ++ nsRefPtr<PlanarYCbCrImage>& aImage) ++{ ++ /* allocate an image using the container */ ++ ImageContainer* container = mDecoder->GetImageContainer(); ++ if (!container) { ++ // We don't have an ImageContainer. We probably belong to an <audio> ++ // element. ++ return GST_FLOW_NOT_SUPPORTED; ++ } ++ ImageFormat format = PLANAR_YCBCR; ++ PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); ++ nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img); ++ ++ /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */ ++ GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new()); ++ GST_BUFFER_SIZE(buf) = aSize; ++ /* allocate the actual YUV buffer */ ++ GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize); ++ ++ aImage = image; ++ ++ /* create a GstMozVideoBufferData to hold the image */ ++ GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image); ++ ++ /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */ ++ gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata); ++ ++ *aBuf = buf; ++ return GST_FLOW_OK; ++} ++ ++gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent) ++{ ++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); ++ switch(GST_EVENT_TYPE(aEvent)) { ++ case GST_EVENT_NEWSEGMENT: ++ { ++ gboolean update; ++ gdouble rate; ++ GstFormat format; ++ gint64 start, stop, position; ++ GstSegment* segment; ++ ++ /* Store the segments so we can convert timestamps to stream time, which ++ * is what the upper layers sync on. ++ */ ++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); ++ gst_event_parse_new_segment(aEvent, &update, &rate, &format, ++ &start, &stop, &position); ++ if (parent == GST_ELEMENT(mVideoAppSink)) ++ segment = &mVideoSegment; ++ else ++ segment = &mAudioSegment; ++ gst_segment_set_newsegment(segment, update, rate, format, ++ start, stop, position); ++ break; ++ } ++ case GST_EVENT_FLUSH_STOP: ++ /* Reset on seeks */ ++ ResetDecode(); ++ break; ++ default: ++ break; ++ } ++ gst_object_unref(parent); ++ ++ return TRUE; ++} ++ ++gboolean GStreamerReader::EventProbeCb(GstPad* aPad, ++ GstEvent* aEvent, ++ gpointer aUserData) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData); ++ return reader->EventProbe(aPad, aEvent); ++} ++ ++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer) ++{ ++ if (!GST_IS_MOZ_VIDEO_BUFFER (aBuffer)) ++ return nullptr; ++ ++ nsRefPtr<PlanarYCbCrImage> image; ++ GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>(gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(aBuffer))); ++ image = bufferdata->mImage; ++ ++ PlanarYCbCrImage::Data data; ++ data.mPicX = data.mPicY = 0; ++ data.mPicSize = nsIntSize(mPicture.width, mPicture.height); ++ data.mStereoMode = STEREO_MODE_MONO; ++ ++ data.mYChannel = GST_BUFFER_DATA(aBuffer); ++ data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width); ++ data.mYSize = nsIntSize(data.mYStride, ++ gst_video_format_get_component_height(mFormat, 0, mPicture.height)); ++ data.mYSkip = 0; ++ data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width); ++ data.mCbCrSize = nsIntSize(data.mCbCrStride, ++ gst_video_format_get_component_height(mFormat, 1, mPicture.height)); ++ data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1, ++ mPicture.width, mPicture.height); ++ data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2, ++ mPicture.width, mPicture.height); ++ data.mCbSkip = 0; ++ data.mCrSkip = 0; ++ ++ image->SetDataNoCopy(data); ++ ++ return image; ++} ++ ++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer, ++ GstBuffer** aOutBuffer, ++ nsRefPtr<PlanarYCbCrImage> &aImage) ++{ ++ AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(aBuffer), ++ GST_BUFFER_SIZE(aBuffer), nullptr, aOutBuffer, aImage); ++ ++ gst_buffer_copy_metadata(*aOutBuffer, aBuffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL); ++ memcpy(GST_BUFFER_DATA(*aOutBuffer), GST_BUFFER_DATA(aBuffer), GST_BUFFER_SIZE(*aOutBuffer)); ++ ++ aImage = GetImageFromBuffer(*aOutBuffer); ++} ++ ++GstCaps* GStreamerReader::BuildAudioSinkCaps() ++{ ++ GstCaps* caps; ++#ifdef IS_LITTLE_ENDIAN ++ int endianness = 1234; ++#else ++ int endianness = 4321; ++#endif ++ gint width; ++#ifdef MOZ_SAMPLE_TYPE_FLOAT32 ++ caps = gst_caps_from_string("audio/x-raw-float, channels={1,2}"); ++ width = 32; ++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */ ++ caps = gst_caps_from_string("audio/x-raw-int, channels={1,2}"); ++ width = 16; ++#endif ++ gst_caps_set_simple(caps, ++ "width", G_TYPE_INT, width, ++ "endianness", G_TYPE_INT, endianness, ++ NULL); ++ ++ return caps; ++} ++ ++void GStreamerReader::InstallPadCallbacks() ++{ ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ gst_pad_add_event_probe(sinkpad, ++ G_CALLBACK(&GStreamerReader::EventProbeCb), this); ++ ++ gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb); ++ gst_pad_set_element_private(sinkpad, this); ++ gst_object_unref(sinkpad); ++ ++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ gst_pad_add_event_probe(sinkpad, ++ G_CALLBACK(&GStreamerReader::EventProbeCb), this); ++ gst_object_unref(sinkpad); ++} diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp new file mode 100644 index 00000000000..a0e8bd8567a --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp @@ -0,0 +1,969 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerReader.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerReader.cpp.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerReader.cpp +@@ -10,8 +10,10 @@ + #include "AbstractMediaDecoder.h" + #include "MediaResource.h" + #include "GStreamerReader.h" ++#if GST_VERSION_MAJOR >= 1 ++#include "GStreamerAllocator.h" ++#endif + #include "GStreamerFormatHelper.h" +-#include "GStreamerMozVideoBuffer.h" + #include "VideoUtils.h" + #include "mozilla/dom/TimeRanges.h" + #include "mozilla/Preferences.h" +@@ -33,14 +35,16 @@ extern PRLogModuleInfo* gMediaDecoderLog + #define LOG(type, msg, ...) + #endif + +-extern bool +-IsYV12Format(const VideoData::YCbCrBuffer::Plane& aYPlane, +- const VideoData::YCbCrBuffer::Plane& aCbPlane, +- const VideoData::YCbCrBuffer::Plane& aCrPlane); +- ++#if DEBUG + static const unsigned int MAX_CHANNELS = 4; +-// Let the demuxer work in pull mode for short files +-static const int SHORT_FILE_SIZE = 1024 * 1024; ++#endif ++// Let the demuxer work in pull mode for short files. This used to be a micro ++// optimization to have more accurate durations for ogg files in mochitests. ++// Since as of today we aren't using gstreamer to demux ogg, and having demuxers ++// work in pull mode over http makes them slower (since they really assume ++// near-zero latency in pull mode) set the constant to 0 for now, which ++// effectively disables it. ++static const int SHORT_FILE_SIZE = 0; + // The default resource->Read() size when working in push mode + static const int DEFAULT_SOURCE_READ_SIZE = 50 * 1024; + +@@ -62,6 +66,10 @@ GStreamerReader::GStreamerReader(Abstrac + : MediaDecoderReader(aDecoder), + mMP3FrameParser(aDecoder->GetResource()->GetLength()), + mUseParserDuration(false), ++#if GST_VERSION_MAJOR >= 1 ++ mAllocator(nullptr), ++ mBufferPool(nullptr), ++#endif + mPlayBin(nullptr), + mBus(nullptr), + mSource(nullptr), +@@ -74,6 +82,9 @@ GStreamerReader::GStreamerReader(Abstrac + mAudioSinkBufferCount(0), + mGstThreadsMonitor("media.gst.threads"), + mReachedEos(false), ++#if GST_VERSION_MAJOR >= 1 ++ mConfigureAlignment(true), ++#endif + fpsNum(0), + fpsDen(0) + { +@@ -85,8 +96,12 @@ GStreamerReader::GStreamerReader(Abstrac + + mSinkCallbacks.eos = GStreamerReader::EosCb; + mSinkCallbacks.new_preroll = GStreamerReader::NewPrerollCb; ++#if GST_VERSION_MAJOR >= 1 ++ mSinkCallbacks.new_sample = GStreamerReader::NewBufferCb; ++#else + mSinkCallbacks.new_buffer = GStreamerReader::NewBufferCb; + mSinkCallbacks.new_buffer_list = nullptr; ++#endif + + gst_segment_init(&mVideoSegment, GST_FORMAT_UNDEFINED); + gst_segment_init(&mAudioSegment, GST_FORMAT_UNDEFINED); +@@ -110,65 +125,59 @@ GStreamerReader::~GStreamerReader() + mAudioAppSink = nullptr; + gst_object_unref(mBus); + mBus = nullptr; ++#if GST_VERSION_MAJOR >= 1 ++ g_object_unref(mAllocator); ++ g_object_unref(mBufferPool); ++#endif + } + } + + nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor) + { +- GError* error = nullptr; +- if (!gst_init_check(0, 0, &error)) { +- LOG(PR_LOG_ERROR, "gst initialization failed: %s", error->message); +- g_error_free(error); +- return NS_ERROR_FAILURE; +- } ++ GStreamerFormatHelper::Instance(); ++ ++#if GST_VERSION_MAJOR >= 1 ++ mAllocator = static_cast<GstAllocator*>(g_object_new(GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR, nullptr)); ++ moz_gfx_memory_allocator_set_reader(mAllocator, this); ++ ++ mBufferPool = static_cast<GstBufferPool*>(g_object_new(GST_TYPE_MOZ_GFX_BUFFER_POOL, nullptr)); ++#endif + ++#if GST_VERSION_MAJOR >= 1 ++ mPlayBin = gst_element_factory_make("playbin", nullptr); ++#else + mPlayBin = gst_element_factory_make("playbin2", nullptr); ++#endif + if (!mPlayBin) { +- LOG(PR_LOG_ERROR, "couldn't create playbin2"); ++ LOG(PR_LOG_ERROR, "couldn't create playbin"); + return NS_ERROR_FAILURE; + } + g_object_set(mPlayBin, "buffer-size", 0, nullptr); + mBus = gst_pipeline_get_bus(GST_PIPELINE(mPlayBin)); + + mVideoSink = gst_parse_bin_from_description("capsfilter name=filter ! " +- "appsink name=videosink sync=true max-buffers=1 " ++ "appsink name=videosink sync=false max-buffers=1 " ++#if GST_VERSION_MAJOR >= 1 ++ "caps=video/x-raw,format=I420" ++#else + "caps=video/x-raw-yuv,format=(fourcc)I420" ++#endif + , TRUE, nullptr); + mVideoAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mVideoSink), + "videosink")); +- gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks, +- (gpointer) this, nullptr); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink"); +- gst_pad_add_event_probe(sinkpad, +- G_CALLBACK(&GStreamerReader::EventProbeCb), this); +- gst_object_unref(sinkpad); +- gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb); +- gst_pad_set_element_private(sinkpad, this); +- + mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! " +-#ifdef MOZ_SAMPLE_TYPE_FLOAT32 +- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-float," +-#ifdef IS_LITTLE_ENDIAN +- "channels={1,2},width=32,endianness=1234", TRUE, nullptr); +-#else +- "channels={1,2},width=32,endianness=4321", TRUE, nullptr); +-#endif +-#else +- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-int," +-#ifdef IS_LITTLE_ENDIAN +- "channels={1,2},width=16,endianness=1234", TRUE, nullptr); +-#else +- "channels={1,2},width=16,endianness=4321", TRUE, nullptr); +-#endif +-#endif ++ "appsink name=audiosink sync=false max-buffers=1", TRUE, nullptr); + mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink), + "audiosink")); ++ GstCaps* caps = BuildAudioSinkCaps(); ++ g_object_set(mAudioAppSink, "caps", caps, nullptr); ++ gst_caps_unref(caps); ++ ++ gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks, ++ (gpointer) this, nullptr); + gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks, + (gpointer) this, nullptr); +- sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink"); +- gst_pad_add_event_probe(sinkpad, +- G_CALLBACK(&GStreamerReader::EventProbeCb), this); +- gst_object_unref(sinkpad); ++ InstallPadCallbacks(); + + g_object_set(mPlayBin, "uri", "appsrc://", + "video-sink", mVideoSink, +@@ -331,7 +340,7 @@ nsresult GStreamerReader::ReadMetadata(M + /* Little trick: set the target caps to "skip" so that playbin2 fails to + * find a decoder for the stream we want to skip. + */ +- GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr); ++ GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr, nullptr); + g_object_set(filter, "caps", filterCaps, nullptr); + gst_caps_unref(filterCaps); + gst_object_unref(filter); +@@ -358,6 +367,7 @@ nsresult GStreamerReader::ReadMetadata(M + gst_message_unref(message); + ret = NS_ERROR_FAILURE; + } else { ++ LOG(PR_LOG_DEBUG, "read metadata pipeline prerolled"); + gst_message_unref(message); + ret = NS_OK; + break; +@@ -371,23 +381,8 @@ nsresult GStreamerReader::ReadMetadata(M + /* we couldn't get this to play */ + return ret; + +- /* FIXME: workaround for a bug in matroskademux. This seek makes matroskademux +- * parse the index */ +- if (gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME, +- GST_SEEK_FLAG_FLUSH, 0)) { +- /* after a seek we need to wait again for ASYNC_DONE */ +- message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE, +- (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR)); +- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) { +- gst_element_set_state(mPlayBin, GST_STATE_NULL); +- gst_message_unref(message); +- return NS_ERROR_FAILURE; +- } +- } +- + /* report the duration */ + gint64 duration; +- GstFormat format = GST_FORMAT_TIME; + + if (isMP3 && mMP3FrameParser.IsMP3()) { + // The MP3FrameParser has reported a duration; use that over the gstreamer +@@ -396,17 +391,25 @@ nsresult GStreamerReader::ReadMetadata(M + mUseParserDuration = true; + mLastParserDuration = mMP3FrameParser.GetDuration(); + mDecoder->SetMediaDuration(mLastParserDuration); +- +- } else if (gst_element_query_duration(GST_ELEMENT(mPlayBin), +- &format, &duration) && format == GST_FORMAT_TIME) { +- // Otherwise use the gstreamer duration. +- ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); +- LOG(PR_LOG_DEBUG, "returning duration %" GST_TIME_FORMAT, GST_TIME_ARGS(duration)); +- duration = GST_TIME_AS_USECONDS (duration); +- mDecoder->SetMediaDuration(duration); +- + } else { +- mDecoder->SetMediaSeekable(false); ++ LOG(PR_LOG_DEBUG, "querying duration"); ++ // Otherwise use the gstreamer duration. ++#if GST_VERSION_MAJOR >= 1 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ GST_FORMAT_TIME, &duration)) { ++#else ++ GstFormat format = GST_FORMAT_TIME; ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ &format, &duration) && format == GST_FORMAT_TIME) { ++#endif ++ ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); ++ LOG(PR_LOG_DEBUG, "have duration %" GST_TIME_FORMAT, ++ GST_TIME_ARGS (duration)); ++ duration = GST_TIME_AS_USECONDS (duration); ++ mDecoder->SetMediaDuration(duration); ++ } else { ++ mDecoder->SetMediaSeekable(false); ++ } + } + + int n_video = 0, n_audio = 0; +@@ -419,7 +422,11 @@ nsresult GStreamerReader::ReadMetadata(M + *aTags = nullptr; + + // Watch the pipeline for fatal errors ++#if GST_VERSION_MAJOR >= 1 ++ gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this, nullptr); ++#else + gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this); ++#endif + + /* set the pipeline to PLAYING so that it starts decoding and queueing data in + * the appsinks */ +@@ -433,19 +440,35 @@ nsresult GStreamerReader::CheckSupported + bool done = false; + bool unsupported = false; + +- GstIterator *it = gst_bin_iterate_recurse(GST_BIN(mPlayBin)); ++ GstIterator* it = gst_bin_iterate_recurse(GST_BIN(mPlayBin)); + while (!done) { ++ GstIteratorResult res; + GstElement* element; +- GstIteratorResult res = gst_iterator_next(it, (void **)&element); ++ ++#if GST_VERSION_MAJOR >= 1 ++ GValue value = {0,}; ++ res = gst_iterator_next(it, &value); ++#else ++ res = gst_iterator_next(it, (void **) &element); ++#endif + switch(res) { + case GST_ITERATOR_OK: + { ++#if GST_VERSION_MAJOR >= 1 ++ element = GST_ELEMENT (g_value_get_object (&value)); ++#endif + GstElementFactory* factory = gst_element_get_factory(element); + if (factory) { + const char* klass = gst_element_factory_get_klass(factory); +- GstPad* pad = gst_element_get_pad(element, "sink"); ++ GstPad* pad = gst_element_get_static_pad(element, "sink"); + if (pad) { +- GstCaps* caps = gst_pad_get_negotiated_caps(pad); ++ GstCaps* caps; ++ ++#if GST_VERSION_MAJOR >= 1 ++ caps = gst_pad_get_current_caps(pad); ++#else ++ caps = gst_pad_get_negotiated_caps(pad); ++#endif + + if (caps) { + /* check for demuxers but ignore elements like id3demux */ +@@ -460,7 +483,11 @@ nsresult GStreamerReader::CheckSupported + } + } + ++#if GST_VERSION_MAJOR >= 1 ++ g_value_unset (&value); ++#else + gst_object_unref(element); ++#endif + done = unsupported; + break; + } +@@ -484,6 +511,8 @@ nsresult GStreamerReader::ResetDecode() + { + nsresult res = NS_OK; + ++ LOG(PR_LOG_DEBUG, "reset decode"); ++ + if (NS_FAILED(MediaDecoderReader::ResetDecode())) { + res = NS_ERROR_FAILURE; + } +@@ -494,6 +523,11 @@ nsresult GStreamerReader::ResetDecode() + mVideoSinkBufferCount = 0; + mAudioSinkBufferCount = 0; + mReachedEos = false; ++#if GST_VERSION_MAJOR >= 1 ++ mConfigureAlignment = true; ++#endif ++ ++ LOG(PR_LOG_DEBUG, "reset decode done"); + + return res; + } +@@ -517,11 +551,11 @@ bool GStreamerReader::DecodeAudioData() + /* We have nothing decoded so it makes no sense to return to the state machine + * as it will call us back immediately, we'll return again and so on, wasting + * CPU cycles for no job done. So, block here until there is either video or +- * audio data available ++ * audio data available + */ + mon.Wait(); + if (!mAudioSinkBufferCount) { +- /* There is still no audio data available, so either there is video data or ++ /* There is still no audio data available, so either there is video data or + * something else has happened (Eos, etc...). Return to the state machine + * to process it. + */ +@@ -533,24 +567,43 @@ bool GStreamerReader::DecodeAudioData() + } + } + ++#if GST_VERSION_MAJOR >= 1 ++ GstSample *sample = gst_app_sink_pull_sample(mAudioAppSink); ++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); ++ gst_sample_unref(sample); ++#else + buffer = gst_app_sink_pull_buffer(mAudioAppSink); ++#endif ++ + mAudioSinkBufferCount--; + } + + int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer); + timestamp = gst_segment_to_stream_time(&mAudioSegment, + GST_FORMAT_TIME, timestamp); ++ + timestamp = GST_TIME_AS_USECONDS(timestamp); + int64_t duration = 0; + if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) + duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); + + int64_t offset = GST_BUFFER_OFFSET(buffer); ++#if GST_VERSION_MAJOR >= 1 ++ GstMapInfo info; ++ gst_buffer_map(buffer, &info, GST_MAP_READ); ++ unsigned int size = info.size; ++#else + unsigned int size = GST_BUFFER_SIZE(buffer); ++#endif + int32_t frames = (size / sizeof(AudioDataValue)) / mInfo.mAudio.mChannels; + ssize_t outSize = static_cast<size_t>(size / sizeof(AudioDataValue)); + nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outSize]); ++#if GST_VERSION_MAJOR >= 1 ++ memcpy(data, info.data, info.size); ++ gst_buffer_unmap(buffer, &info); ++#else + memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); ++#endif + AudioData* audio = new AudioData(offset, timestamp, duration, + frames, data.forget(), mInfo.mAudio.mChannels); + +@@ -561,7 +614,7 @@ bool GStreamerReader::DecodeAudioData() + } + + bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip, +- int64_t aTimeThreshold) ++ int64_t aTimeThreshold) + { + NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); + +@@ -580,11 +633,11 @@ bool GStreamerReader::DecodeVideoFrame(b + /* We have nothing decoded so it makes no sense to return to the state machine + * as it will call us back immediately, we'll return again and so on, wasting + * CPU cycles for no job done. So, block here until there is either video or +- * audio data available ++ * audio data available + */ + mon.Wait(); + if (!mVideoSinkBufferCount) { +- /* There is still no video data available, so either there is audio data or ++ /* There is still no video data available, so either there is audio data or + * something else has happened (Eos, etc...). Return to the state machine + * to process it + */ +@@ -598,11 +651,17 @@ bool GStreamerReader::DecodeVideoFrame(b + + mDecoder->NotifyDecodedFrames(0, 1); + ++#if GST_VERSION_MAJOR >= 1 ++ GstSample *sample = gst_app_sink_pull_sample(mVideoAppSink); ++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample)); ++ gst_sample_unref(sample); ++#else + buffer = gst_app_sink_pull_buffer(mVideoAppSink); ++#endif + mVideoSinkBufferCount--; + } + +- bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); ++ bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + if ((aKeyFrameSkip && !isKeyframe)) { + gst_buffer_unref(buffer); + return true; +@@ -618,73 +677,55 @@ bool GStreamerReader::DecodeVideoFrame(b + "frame has invalid timestamp"); + + timestamp = GST_TIME_AS_USECONDS(timestamp); ++ int64_t duration; ++ if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) ++ duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); ++ else if (fpsNum && fpsDen) ++ /* add 1-frame duration */ ++ duration = gst_util_uint64_scale(GST_USECOND, fpsDen, fpsNum); ++ + if (timestamp < aTimeThreshold) { + LOG(PR_LOG_DEBUG, "skipping frame %" GST_TIME_FORMAT +- " threshold %" GST_TIME_FORMAT, +- GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)); ++ " threshold %" GST_TIME_FORMAT, ++ GST_TIME_ARGS(timestamp * 1000), ++ GST_TIME_ARGS(aTimeThreshold * 1000)); + gst_buffer_unref(buffer); + return true; + } +- + if (!buffer) + /* no more frames */ + return false; + +- int64_t duration = 0; +- if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer))) +- duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer)); +- else if (fpsNum && fpsDen) +- /* 1-frame duration */ +- duration = gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen); +- +- nsRefPtr<PlanarYCbCrImage> image; +- GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*> +- GST_IS_MOZ_VIDEO_BUFFER(buffer)?gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(buffer)):nullptr; +- +- if(bufferdata) +- image = bufferdata->mImage; ++#if GST_VERSION_MAJOR >= 1 ++ if (mConfigureAlignment && buffer->pool) { ++ GstStructure *config = gst_buffer_pool_get_config(buffer->pool); ++ GstVideoAlignment align; ++ if (gst_buffer_pool_config_get_video_alignment(config, &align)) ++ gst_video_info_align(&mVideoInfo, &align); ++ gst_structure_free(config); ++ mConfigureAlignment = false; ++ } ++#endif + ++ nsRefPtr<PlanarYCbCrImage> image = GetImageFromBuffer(buffer); + if (!image) { + /* Ugh, upstream is not calling gst_pad_alloc_buffer(). Fallback to + * allocating a PlanarYCbCrImage backed GstBuffer here and memcpy. + */ + GstBuffer* tmp = nullptr; +- AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(buffer), +- GST_BUFFER_SIZE(buffer), nullptr, &tmp, image); +- +- /* copy */ +- gst_buffer_copy_metadata(tmp, buffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL); +- memcpy(GST_BUFFER_DATA(tmp), GST_BUFFER_DATA(buffer), +- GST_BUFFER_SIZE(tmp)); ++ CopyIntoImageBuffer(buffer, &tmp, image); + gst_buffer_unref(buffer); + buffer = tmp; + } + +- guint8* data = GST_BUFFER_DATA(buffer); +- +- int width = mPicture.width; +- int height = mPicture.height; +- GstVideoFormat format = mFormat; +- +- VideoData::YCbCrBuffer b; +- for(int i = 0; i < 3; i++) { +- b.mPlanes[i].mData = data + gst_video_format_get_component_offset(format, i, +- width, height); +- b.mPlanes[i].mStride = gst_video_format_get_row_stride(format, i, width); +- b.mPlanes[i].mHeight = gst_video_format_get_component_height(format, +- i, height); +- b.mPlanes[i].mWidth = gst_video_format_get_component_width(format, +- i, width); +- b.mPlanes[i].mOffset = 0; +- b.mPlanes[i].mSkip = 0; +- } +- +- isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + int64_t offset = mDecoder->GetResource()->Tell(); // Estimate location in media. +- VideoData* video = VideoData::Create(mInfo.mVideo, image, offset, +- timestamp, duration, b, +- isKeyframe, -1, mPicture); ++ VideoData* video = VideoData::CreateFromImage(mInfo.mVideo, ++ mDecoder->GetImageContainer(), ++ offset, timestamp, duration, ++ static_cast<Image*>(image.get()), ++ isKeyframe, -1, mPicture); + mVideoQueue.Push(video); ++ + gst_buffer_unref(buffer); + + return true; +@@ -707,6 +748,10 @@ nsresult GStreamerReader::Seek(int64_t a + return NS_ERROR_FAILURE; + } + LOG(PR_LOG_DEBUG, "seek succeeded"); ++ GstMessage* message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE, ++ (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR)); ++ gst_message_unref(message); ++ LOG(PR_LOG_DEBUG, "seek completed"); + + return DecodeToTarget(aTarget); + } +@@ -718,7 +763,9 @@ nsresult GStreamerReader::GetBuffered(do + return NS_OK; + } + ++#if GST_VERSION_MAJOR == 0 + GstFormat format = GST_FORMAT_TIME; ++#endif + MediaResource* resource = mDecoder->GetResource(); + nsTArray<MediaByteRange> ranges; + resource->GetCachedRanges(ranges); +@@ -740,12 +787,21 @@ nsresult GStreamerReader::GetBuffered(do + int64_t endOffset = ranges[index].mEnd; + gint64 startTime, endTime; + ++#if GST_VERSION_MAJOR >= 1 ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, ++ startOffset, GST_FORMAT_TIME, &startTime)) ++ continue; ++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, ++ endOffset, GST_FORMAT_TIME, &endTime)) ++ continue; ++#else + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, + startOffset, &format, &startTime) || format != GST_FORMAT_TIME) + continue; + if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, + endOffset, &format, &endTime) || format != GST_FORMAT_TIME) + continue; ++#endif + + double start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND; + double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND; +@@ -766,7 +822,13 @@ void GStreamerReader::ReadAndPushData(gu + nsresult rv = NS_OK; + + GstBuffer* buffer = gst_buffer_new_and_alloc(aLength); ++#if GST_VERSION_MAJOR >= 1 ++ GstMapInfo info; ++ gst_buffer_map(buffer, &info, GST_MAP_WRITE); ++ guint8 *data = info.data; ++#else + guint8* data = GST_BUFFER_DATA(buffer); ++#endif + uint32_t size = 0, bytesRead = 0; + while(bytesRead < aLength) { + rv = resource->Read(reinterpret_cast<char*>(data + bytesRead), +@@ -780,7 +842,12 @@ void GStreamerReader::ReadAndPushData(gu + int64_t offset2 = resource->Tell(); + unused << offset2; + ++#if GST_VERSION_MAJOR >= 1 ++ gst_buffer_unmap(buffer, &info); ++ gst_buffer_set_size(buffer, bytesRead); ++#else + GST_BUFFER_SIZE(buffer) = bytesRead; ++#endif + + GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer)); + if (ret != GST_FLOW_OK) { +@@ -813,8 +880,13 @@ int64_t GStreamerReader::QueryDuration() + gint64 duration = 0; + GstFormat format = GST_FORMAT_TIME; + ++#if GST_VERSION_MAJOR >= 1 ++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin), ++ format, &duration)) { ++#else + if (gst_element_query_duration(GST_ELEMENT(mPlayBin), + &format, &duration)) { ++#endif + if (format == GST_FORMAT_TIME) { + LOG(PR_LOG_DEBUG, "pipeline duration %" GST_TIME_FORMAT, + GST_TIME_ARGS (duration)); +@@ -893,108 +965,6 @@ gboolean GStreamerReader::SeekData(GstAp + return NS_SUCCEEDED(rv); + } + +-gboolean GStreamerReader::EventProbeCb(GstPad* aPad, +- GstEvent* aEvent, +- gpointer aUserData) +-{ +- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData); +- return reader->EventProbe(aPad, aEvent); +-} +- +-gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent) +-{ +- GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); +- switch(GST_EVENT_TYPE(aEvent)) { +- case GST_EVENT_NEWSEGMENT: +- { +- gboolean update; +- gdouble rate; +- GstFormat format; +- gint64 start, stop, position; +- GstSegment* segment; +- +- /* Store the segments so we can convert timestamps to stream time, which +- * is what the upper layers sync on. +- */ +- ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); +- gst_event_parse_new_segment(aEvent, &update, &rate, &format, +- &start, &stop, &position); +- if (parent == GST_ELEMENT(mVideoAppSink)) +- segment = &mVideoSegment; +- else +- segment = &mAudioSegment; +- gst_segment_set_newsegment(segment, update, rate, format, +- start, stop, position); +- break; +- } +- case GST_EVENT_FLUSH_STOP: +- /* Reset on seeks */ +- ResetDecode(); +- break; +- default: +- break; +- } +- gst_object_unref(parent); +- +- return TRUE; +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf, +- nsRefPtr<PlanarYCbCrImage>& aImage) +-{ +- /* allocate an image using the container */ +- ImageContainer* container = mDecoder->GetImageContainer(); +- if (!container) { +- // We don't have an ImageContainer. We probably belong to an <audio> +- // element. +- return GST_FLOW_NOT_SUPPORTED; +- } +- ImageFormat format = PLANAR_YCBCR; +- PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get()); +- nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img); +- +- /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */ +- GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new()); +- GST_BUFFER_SIZE(buf) = aSize; +- /* allocate the actual YUV buffer */ +- GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize); +- +- aImage = image; +- +- /* create a GstMozVideoBufferData to hold the image */ +- GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image); +- +- /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */ +- gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata); +- +- *aBuf = buf; +- return GST_FLOW_OK; +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf) +-{ +- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); +- return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf); +-} +- +-GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad, +- guint64 aOffset, +- guint aSize, +- GstCaps* aCaps, +- GstBuffer** aBuf) +-{ +- nsRefPtr<PlanarYCbCrImage> image; +- return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image); +-} +- + GstFlowReturn GStreamerReader::NewPrerollCb(GstAppSink* aSink, + gpointer aUserData) + { +@@ -1011,8 +981,12 @@ void GStreamerReader::AudioPreroll() + { + /* The first audio buffer has reached the audio sink. Get rate and channels */ + LOG(PR_LOG_DEBUG, "Audio preroll"); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++#if GST_VERSION_MAJOR >= 1 ++ GstCaps *caps = gst_pad_get_current_caps(sinkpad); ++#else + GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad); ++#endif + GstStructure* s = gst_caps_get_structure(caps, 0); + mInfo.mAudio.mRate = mInfo.mAudio.mChannels = 0; + gst_structure_get_int(s, "rate", (gint*) &mInfo.mAudio.mRate); +@@ -1030,9 +1004,18 @@ void GStreamerReader::VideoPreroll() + { + /* The first video buffer has reached the video sink. Get width and height */ + LOG(PR_LOG_DEBUG, "Video preroll"); +- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++#if GST_VERSION_MAJOR >= 1 ++ GstCaps* caps = gst_pad_get_current_caps(sinkpad); ++ memset (&mVideoInfo, 0, sizeof (mVideoInfo)); ++ gst_video_info_from_caps(&mVideoInfo, caps); ++ mFormat = mVideoInfo.finfo->format; ++ mPicture.width = mVideoInfo.width; ++ mPicture.height = mVideoInfo.height; ++#else + GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad); + gst_video_format_parse_caps(caps, &mFormat, &mPicture.width, &mPicture.height); ++#endif + GstStructure* structure = gst_caps_get_structure(caps, 0); + gst_structure_get_fraction(structure, "framerate", &fpsNum, &fpsDen); + NS_ASSERTION(mPicture.width && mPicture.height, "invalid video resolution"); +@@ -1061,6 +1044,7 @@ void GStreamerReader::NewVideoBuffer() + /* We have a new video buffer queued in the video sink. Increment the counter + * and notify the decode thread potentially blocked in DecodeVideoFrame + */ ++ + mDecoder->NotifyDecodedFrames(1, 0); + mVideoSinkBufferCount++; + mon.NotifyAll(); +@@ -1197,5 +1181,199 @@ void GStreamerReader::NotifyDataArrived( + } + } + ++#if GST_VERSION_MAJOR >= 1 ++GstCaps* GStreamerReader::BuildAudioSinkCaps() ++{ ++ GstCaps* caps = gst_caps_from_string("audio/x-raw, channels={1,2}"); ++ const char* format; ++#ifdef MOZ_SAMPLE_TYPE_FLOAT32 ++#ifdef IS_LITTLE_ENDIAN ++ format = "F32LE"; ++#else ++ format = "F32BE"; ++#endif ++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */ ++#ifdef IS_LITTLE_ENDIAN ++ format = "S16LE"; ++#else ++ format = "S16BE"; ++#endif ++#endif ++ gst_caps_set_simple(caps, "format", G_TYPE_STRING, format, nullptr); ++ ++ return caps; ++} ++ ++void GStreamerReader::InstallPadCallbacks() ++{ ++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink"); ++ ++ gst_pad_add_probe(sinkpad, ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | ++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_FLUSH), ++ &GStreamerReader::EventProbeCb, this, nullptr); ++ gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, ++ GStreamerReader::QueryProbeCb, nullptr, nullptr); ++ ++ gst_pad_set_element_private(sinkpad, this); ++ gst_object_unref(sinkpad); ++ ++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink"); ++ gst_pad_add_probe(sinkpad, ++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING | ++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | ++ GST_PAD_PROBE_TYPE_EVENT_FLUSH), ++ &GStreamerReader::EventProbeCb, this, nullptr); ++ gst_object_unref(sinkpad); ++} ++ ++GstPadProbeReturn GStreamerReader::EventProbeCb(GstPad *aPad, ++ GstPadProbeInfo *aInfo, ++ gpointer aUserData) ++{ ++ GStreamerReader *reader = (GStreamerReader *) aUserData; ++ GstEvent *aEvent = (GstEvent *)aInfo->data; ++ return reader->EventProbe(aPad, aEvent); ++} ++ ++GstPadProbeReturn GStreamerReader::EventProbe(GstPad *aPad, GstEvent *aEvent) ++{ ++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad)); ++ ++ LOG(PR_LOG_DEBUG, "event probe %s", GST_EVENT_TYPE_NAME (aEvent)); ++ ++ switch(GST_EVENT_TYPE(aEvent)) { ++ case GST_EVENT_SEGMENT: ++ { ++ const GstSegment *newSegment; ++ GstSegment* segment; ++ ++ /* Store the segments so we can convert timestamps to stream time, which ++ * is what the upper layers sync on. ++ */ ++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor); ++#if GST_VERSION_MINOR <= 1 && GST_VERSION_MICRO < 1 ++ ResetDecode(); ++#endif ++ gst_event_parse_segment(aEvent, &newSegment); ++ if (parent == GST_ELEMENT(mVideoAppSink)) ++ segment = &mVideoSegment; ++ else ++ segment = &mAudioSegment; ++ gst_segment_copy_into (newSegment, segment); ++ break; ++ } ++ case GST_EVENT_FLUSH_STOP: ++ /* Reset on seeks */ ++ ResetDecode(); ++ break; ++ default: ++ break; ++ } ++ gst_object_unref(parent); ++ ++ return GST_PAD_PROBE_OK; ++} ++ ++GstPadProbeReturn GStreamerReader::QueryProbeCb(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData) ++{ ++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad)); ++ return reader->QueryProbe(aPad, aInfo, aUserData); ++} ++ ++GstPadProbeReturn GStreamerReader::QueryProbe(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData) ++{ ++ GstQuery *query = gst_pad_probe_info_get_query(aInfo); ++ GstPadProbeReturn ret = GST_PAD_PROBE_OK; ++ ++ switch (GST_QUERY_TYPE (query)) { ++ case GST_QUERY_ALLOCATION: ++ GstCaps *caps; ++ GstVideoInfo info; ++ gboolean need_pool; ++ ++ gst_query_parse_allocation(query, &caps, &need_pool); ++ gst_video_info_init(&info); ++ gst_video_info_from_caps(&info, caps); ++ gst_query_add_allocation_param(query, mAllocator, nullptr); ++ gst_query_add_allocation_pool(query, mBufferPool, info.size, 0, 0); ++ gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, nullptr); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++void GStreamerReader::ImageDataFromVideoFrame(GstVideoFrame *aFrame, ++ PlanarYCbCrImage::Data *aData) ++{ ++ NS_ASSERTION(GST_VIDEO_INFO_IS_YUV(&mVideoInfo), ++ "Non-YUV video frame formats not supported"); ++ NS_ASSERTION(GST_VIDEO_FRAME_N_COMPONENTS(aFrame) == 3, ++ "Unsupported number of components in video frame"); ++ ++ aData->mPicX = aData->mPicY = 0; ++ aData->mPicSize = nsIntSize(mPicture.width, mPicture.height); ++ aData->mStereoMode = STEREO_MODE_MONO; ++ ++ aData->mYChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 0); ++ aData->mYStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 0); ++ aData->mYSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 0), ++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 0)); ++ aData->mYSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 0) - 1; ++ aData->mCbCrStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 1); ++ aData->mCbCrSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 1), ++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 1)); ++ aData->mCbChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 1); ++ aData->mCrChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 2); ++ aData->mCbSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 1) - 1; ++ aData->mCrSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 2) - 1; ++} ++ ++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer) ++{ ++ nsRefPtr<PlanarYCbCrImage> image = nullptr; ++ ++ if (gst_buffer_n_memory(aBuffer) == 1) { ++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); ++ if (GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator)) { ++ image = moz_gfx_memory_get_image(mem); ++ ++ GstVideoFrame frame; ++ gst_video_frame_map(&frame, &mVideoInfo, aBuffer, GST_MAP_READ); ++ PlanarYCbCrImage::Data data; ++ ImageDataFromVideoFrame(&frame, &data); ++ image->SetDataNoCopy(data); ++ gst_video_frame_unmap(&frame); ++ } ++ } ++ ++ return image; ++} ++ ++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer, ++ GstBuffer** aOutBuffer, ++ nsRefPtr<PlanarYCbCrImage> &image) ++{ ++ *aOutBuffer = gst_buffer_new_allocate(mAllocator, gst_buffer_get_size(aBuffer), nullptr); ++ GstMemory *mem = gst_buffer_peek_memory(*aOutBuffer, 0); ++ GstMapInfo map_info; ++ gst_memory_map(mem, &map_info, GST_MAP_WRITE); ++ gst_buffer_extract(aBuffer, 0, map_info.data, gst_buffer_get_size(aBuffer)); ++ gst_memory_unmap(mem, &map_info); ++ ++ /* create a new gst buffer with the newly created memory and copy the ++ * metadata over from the incoming buffer */ ++ gst_buffer_copy_into(*aOutBuffer, aBuffer, ++ (GstBufferCopyFlags)(GST_BUFFER_COPY_METADATA), 0, -1); ++ image = GetImageFromBuffer(*aOutBuffer); ++} ++#endif ++ + } // namespace mozilla + diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h new file mode 100644 index 00000000000..cc6fa481bd2 --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h @@ -0,0 +1,103 @@ +$NetBSD: patch-content_media_gstreamer_GStreamerReader.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/GStreamerReader.h.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/GStreamerReader.h +@@ -22,6 +22,7 @@ + + #include "MediaDecoderReader.h" + #include "MP3FrameParser.h" ++#include "ImageContainer.h" + #include "nsRect.h" + + namespace mozilla { +@@ -30,10 +31,6 @@ namespace dom { + class TimeRanges; + } + +-namespace layers { +-class PlanarYCbCrImage; +-} +- + class AbstractMediaDecoder; + + class GStreamerReader : public MediaDecoderReader +@@ -67,10 +64,20 @@ public: + return mInfo.HasVideo(); + } + ++ layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); } ++ + private: + + void ReadAndPushData(guint aLength); + int64_t QueryDuration(); ++ nsRefPtr<layers::PlanarYCbCrImage> GetImageFromBuffer(GstBuffer* aBuffer); ++ void CopyIntoImageBuffer(GstBuffer *aBuffer, GstBuffer** aOutBuffer, nsRefPtr<layers::PlanarYCbCrImage> &image); ++ GstCaps* BuildAudioSinkCaps(); ++ void InstallPadCallbacks(); ++ ++#if GST_VERSION_MAJOR >= 1 ++ void ImageDataFromVideoFrame(GstVideoFrame *aFrame, layers::PlanarYCbCrImage::Data *aData); ++#endif + + /* Called once the pipeline is setup to check that the stream only contains + * supported formats +@@ -105,20 +112,31 @@ private: + gboolean SeekData(GstAppSrc* aSrc, guint64 aOffset); + + /* Called when events reach the sinks. See inline comments */ ++#if GST_VERSION_MAJOR == 1 ++ static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++ GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent); ++#else + static gboolean EventProbeCb(GstPad* aPad, GstEvent* aEvent, gpointer aUserData); + gboolean EventProbe(GstPad* aPad, GstEvent* aEvent); ++#endif + +- /* Called when elements in the video branch of the pipeline call +- * gst_pad_alloc_buffer(). Used to provide PlanarYCbCrImage backed GstBuffers +- * to the pipeline so that a memory copy can be avoided when handling YUV +- * buffers from the pipeline to the gfx side. +- */ ++ /* Called when the video part of the pipeline allocates buffers. Used to ++ * provide PlanarYCbCrImage backed GstBuffers to the pipeline so that a memory ++ * copy can be avoided when handling YUV buffers from the pipeline to the gfx ++ * side. ++ */ ++#if GST_VERSION_MAJOR == 1 ++ static GstPadProbeReturn QueryProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++ GstPadProbeReturn QueryProbe(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData); ++#else + static GstFlowReturn AllocateVideoBufferCb(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf); + GstFlowReturn AllocateVideoBufferFull(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf, nsRefPtr<layers::PlanarYCbCrImage>& aImage); + GstFlowReturn AllocateVideoBuffer(GstPad* aPad, guint64 aOffset, guint aSize, + GstCaps* aCaps, GstBuffer** aBuf); ++#endif ++ + + /* Called when the pipeline is prerolled, that is when at start or after a + * seek, the first audio and video buffers are queued in the sinks. +@@ -167,6 +185,11 @@ private: + bool mUseParserDuration; + int64_t mLastParserDuration; + ++#if GST_VERSION_MAJOR >= 1 ++ GstAllocator *mAllocator; ++ GstBufferPool *mBufferPool; ++ GstVideoInfo mVideoInfo; ++#endif + GstElement* mPlayBin; + GstBus* mBus; + GstAppSrc* mSource; +@@ -197,6 +220,9 @@ private: + * DecodeAudioData and DecodeVideoFrame should not expect any more data + */ + bool mReachedEos; ++#if GST_VERSION_MAJOR >= 1 ++ bool mConfigureAlignment; ++#endif + int fpsNum; + int fpsDen; + }; diff --git a/www/firefox/patches/patch-content_media_gstreamer_moz.build b/www/firefox/patches/patch-content_media_gstreamer_moz.build new file mode 100644 index 00000000000..6badf82e80e --- /dev/null +++ b/www/firefox/patches/patch-content_media_gstreamer_moz.build @@ -0,0 +1,25 @@ +$NetBSD: patch-content_media_gstreamer_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/gstreamer/moz.build.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/gstreamer/moz.build +@@ -15,10 +15,19 @@ SOURCES += [ + 'GStreamerDecoder.cpp', + 'GStreamerFormatHelper.cpp', + 'GStreamerLoader.cpp', +- 'GStreamerMozVideoBuffer.cpp', + 'GStreamerReader.cpp', + ] + ++if CONFIG['GST_API_VERSION'] == '1.0': ++ SOURCES += [ ++ 'GStreamerAllocator.cpp', ++ ] ++else: ++ SOURCES += [ ++ 'GStreamerMozVideoBuffer.cpp', ++ 'GStreamerReader-0.10.cpp', ++ ] ++ + FAIL_ON_WARNINGS = True + + FINAL_LIBRARY = 'gklayout' diff --git a/www/firefox/patches/patch-content_media_test_manifest.js b/www/firefox/patches/patch-content_media_test_manifest.js new file mode 100644 index 00000000000..a91d314d1e9 --- /dev/null +++ b/www/firefox/patches/patch-content_media_test_manifest.js @@ -0,0 +1,17 @@ +$NetBSD: patch-content_media_test_manifest.js,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- content/media/test/manifest.js.orig 2014-03-15 05:19:11.000000000 +0000 ++++ content/media/test/manifest.js +@@ -357,9 +357,9 @@ var gUnseekableTests = [ + { name:"bogus.duh", type:"bogus/duh"} + ]; + // Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so +-// only include it in the unseekable tests if we're on later versions of Windows. +-if (navigator.userAgent.indexOf("Windows") == -1 || +- IsWindows8OrLater()) { ++// only include it in the unseekable tests if we're on later versions of Windows. ++// This test actually only passes on win8 at the moment. ++if (navigator.userAgent.indexOf("Windows") != -1 && IsWindows8OrLater()) { + gUnseekableTests = gUnseekableTests.concat([ + { name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" } + ]); diff --git a/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp b/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp deleted file mode 100644 index 94cecf8501e..00000000000 --- a/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp +++ /dev/null @@ -1,14 +0,0 @@ -$NetBSD: patch-extensions_auth_nsAuthGSSAPI.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ - ---- extensions/auth/nsAuthGSSAPI.cpp.orig 2013-05-11 19:19:29.000000000 +0000 -+++ extensions/auth/nsAuthGSSAPI.cpp -@@ -39,6 +39,9 @@ typedef KLStatus (*KLCacheHasValidTicket - #endif - - #if defined(HAVE_RES_NINIT) -+#include <sys/types.h> -+#include <netinet/in.h> -+#include <arpa/nameser.h> - #include <resolv.h> - #endif - diff --git a/www/firefox/patches/patch-gfx_moz.build b/www/firefox/patches/patch-gfx_moz.build new file mode 100644 index 00000000000..1ca5a603ba2 --- /dev/null +++ b/www/firefox/patches/patch-gfx_moz.build @@ -0,0 +1,26 @@ +$NetBSD: patch-gfx_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- gfx/moz.build.orig 2014-03-15 05:19:16.000000000 +0000 ++++ gfx/moz.build +@@ -7,6 +7,12 @@ + if CONFIG['MOZ_TREE_CAIRO']: + DIRS += ['cairo'] + ++if not CONFIG['MOZ_NATIVE_GRAPHITE2']: ++ DIRS += ['graphite2/src' ] ++ ++if not CONFIG['MOZ_NATIVE_HARFBUZZ']: ++ DIRS += ['harfbuzz/src'] ++ + DIRS += [ + '2d', + 'ycbcr', +@@ -15,8 +21,6 @@ DIRS += [ + 'qcms', + 'gl', + 'layers', +- 'graphite2/src', +- 'harfbuzz/src', + 'ots/src', + 'thebes', + 'ipc', diff --git a/www/firefox/patches/patch-gfx_skia_Makefile.in b/www/firefox/patches/patch-gfx_skia_Makefile.in new file mode 100644 index 00000000000..bbc919b294c --- /dev/null +++ b/www/firefox/patches/patch-gfx_skia_Makefile.in @@ -0,0 +1,15 @@ +$NetBSD: patch-gfx_skia_Makefile.in,v 1.3 2014/03/20 21:02:00 ryoon Exp $ + +--- gfx/skia/Makefile.in.orig 2014-03-15 05:19:16.000000000 +0000 ++++ gfx/skia/Makefile.in +@@ -34,6 +34,10 @@ ifeq (qt,$(MOZ_WIDGET_TOOLKIT)) + OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS) + endif + ++ifdef MOZ_NATIVE_HARFBUZZ ++OS_CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + include $(topsrcdir)/config/rules.mk + + ifneq (,$(INTEL_ARCHITECTURE)) diff --git a/www/firefox/patches/patch-gfx_skia_moz.build b/www/firefox/patches/patch-gfx_skia_moz.build index f3c2e35731c..8d5012ca5a9 100644 --- a/www/firefox/patches/patch-gfx_skia_moz.build +++ b/www/firefox/patches/patch-gfx_skia_moz.build @@ -1,10 +1,10 @@ -$NetBSD: patch-gfx_skia_moz.build,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-gfx_skia_moz.build,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- gfx/skia/moz.build.orig 2014-02-12 21:29:00.000000000 +0000 +--- gfx/skia/moz.build.orig 2014-03-15 05:19:16.000000000 +0000 +++ gfx/skia/moz.build -@@ -197,7 +197,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt +@@ -209,7 +209,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt + 'src/ports/SkFontHost_cairo.cpp', 'src/ports/SkFontHost_FreeType_common.cpp', - 'src/utils/SkOSFile.cpp', ] - if CONFIG['OS_TARGET'] == 'Linux': + if CONFIG['MOZ_X11'] == 1 or CONFIG['OS_TARGET'] == 'Linux': diff --git a/www/firefox/patches/patch-gfx_thebes_Makefile.in b/www/firefox/patches/patch-gfx_thebes_Makefile.in new file mode 100644 index 00000000000..f27dff74010 --- /dev/null +++ b/www/firefox/patches/patch-gfx_thebes_Makefile.in @@ -0,0 +1,19 @@ +$NetBSD: patch-gfx_thebes_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- gfx/thebes/Makefile.in.orig 2014-03-15 05:19:16.000000000 +0000 ++++ gfx/thebes/Makefile.in +@@ -13,6 +13,14 @@ DEFINES := $(filter-out -DUNICODE,$(DEFI + CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS) + CFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS) + ++ifdef MOZ_NATIVE_GRAPHITE2 ++CXXFLAGS += $(MOZ_GRAPHITE2_CFLAGS) ++endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS) ++endif ++ + ifeq ($(MOZ_WIDGET_TOOLKIT),android) + CXXFLAGS += $(CAIRO_FT_CFLAGS) + endif diff --git a/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in b/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in new file mode 100644 index 00000000000..6bc3763cd28 --- /dev/null +++ b/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-intl_unicharutil_util_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- intl/unicharutil/util/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000 ++++ intl/unicharutil/util/Makefile.in +@@ -19,3 +19,7 @@ ifdef _MSC_VER + OS_COMPILE_CXXFLAGS += -Zl + OS_COMPILE_CFLAGS += -Zl + endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++nsUnicodePropertyData.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif diff --git a/www/firefox/patches/patch-ipc_chromium_Makefile.in b/www/firefox/patches/patch-ipc_chromium_Makefile.in index 20868feb346..b584dd7e743 100644 --- a/www/firefox/patches/patch-ipc_chromium_Makefile.in +++ b/www/firefox/patches/patch-ipc_chromium_Makefile.in @@ -1,8 +1,8 @@ -$NetBSD: patch-ipc_chromium_Makefile.in,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-ipc_chromium_Makefile.in,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- ipc/chromium/Makefile.in.orig 2013-10-25 22:27:21.000000000 +0000 +--- ipc/chromium/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000 +++ ipc/chromium/Makefile.in -@@ -22,9 +22,7 @@ vpath %.c \ +@@ -11,9 +11,7 @@ vpath %.c \ $(srcdir)/src/third_party/libevent \ $(NULL) else # } else { @@ -13,37 +13,3 @@ $NetBSD: patch-ipc_chromium_Makefile.in,v 1.5 2014/02/20 13:19:03 ryoon Exp $ endif # } vpath %.cc \ -@@ -45,6 +43,33 @@ DEFINES += -DANDROID -D_POSIX_MONOTONIC_ - endif # Android - endif # } Not WINNT (OS_POSIX) - -+ifdef OS_SOLARIS # { -+ -+CPPSRCS += \ -+ atomicops_internals_x86_gcc.cc \ -+ process_util_linux.cc \ -+ time_posix.cc \ -+ $(NULL) -+ -+ifdef MOZ_ENABLE_GTK2 -+CPPSRCS += \ -+ message_pump_glib.cc \ -+ $(NULL) -+endif -+ -+ifdef MOZ_ENABLE_QT -+MOCSRCS = \ -+ moc_message_pump_qt.cc \ -+ $(NULL) -+ -+CPPSRCS += \ -+ $(MOCSRCS) \ -+ message_pump_qt.cc \ -+ $(NULL) -+endif -+ -+endif # } OS_SOLARIS -+ - # libevent - - ifndef MOZ_NATIVE_LIBEVENT # { diff --git a/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp b/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp index 19b83b8040f..3c0dbc624d9 100644 --- a/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp +++ b/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp @@ -1,6 +1,6 @@ -$NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- ipc/glue/GeckoChildProcessHost.cpp.orig 2013-07-30 00:58:17.000000000 +0000 +--- ipc/glue/GeckoChildProcessHost.cpp.orig 2014-03-15 05:19:19.000000000 +0000 +++ ipc/glue/GeckoChildProcessHost.cpp @@ -4,7 +4,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -14,9 +14,9 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo +_Pragma("GCC visibility pop") +#endif - #include "base/command_line.h" - #include "base/path_service.h" -@@ -490,7 +496,7 @@ GeckoChildProcessHost::PerformAsyncLaunc + #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + #include "sandboxBroker.h" +@@ -499,7 +505,7 @@ GeckoChildProcessHost::PerformAsyncLaunc // and passing wstrings from one config to the other is unsafe. So // we split the logic here. @@ -25,7 +25,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo base::environment_map newEnvVars; ChildPrivileges privs = mPrivileges; if (privs == base::PRIVILEGES_DEFAULT) { -@@ -509,7 +515,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -518,7 +524,7 @@ GeckoChildProcessHost::PerformAsyncLaunc if (NS_SUCCEEDED(rv)) { nsCString path; greDir->GetNativePath(path); @@ -34,7 +34,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo # if defined(MOZ_WIDGET_ANDROID) path += "/lib"; # endif // MOZ_WIDGET_ANDROID -@@ -618,7 +624,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -627,7 +633,7 @@ GeckoChildProcessHost::PerformAsyncLaunc childArgv.push_back(pidstring); #if defined(MOZ_CRASHREPORTER) @@ -43,7 +43,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo int childCrashFd, childCrashRemapFd; if (!CrashReporter::CreateNotificationPipeForChild( &childCrashFd, &childCrashRemapFd)) -@@ -651,7 +657,7 @@ GeckoChildProcessHost::PerformAsyncLaunc +@@ -660,7 +666,7 @@ GeckoChildProcessHost::PerformAsyncLaunc childArgv.push_back(childProcessType); base::LaunchApp(childArgv, mFileMap, diff --git a/www/firefox/patches/patch-js_src_Makefile.in b/www/firefox/patches/patch-js_src_Makefile.in index a6304978041..f3cd1fd2e8f 100644 --- a/www/firefox/patches/patch-js_src_Makefile.in +++ b/www/firefox/patches/patch-js_src_Makefile.in @@ -1,18 +1,13 @@ -$NetBSD: patch-js_src_Makefile.in,v 1.6 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-js_src_Makefile.in,v 1.7 2014/03/20 21:02:00 ryoon Exp $ ---- js/src/Makefile.in.orig 2013-12-05 16:07:35.000000000 +0000 +--- js/src/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000 +++ js/src/Makefile.in -@@ -467,6 +467,13 @@ EXTRA_LIBS += -lposix4 -ldl -lnsl -lsock - endif +@@ -379,7 +379,7 @@ endif + ifdef MOZ_SHARED_ICU + EXTRA_DSO_LDOPTS += $(MOZ_ICU_LIBS) + else +-SHARED_LIBRARY_LIBS += $(MOZ_ICU_LIBS) ++SHARED_LIBRARY_LIBS += $(filter-out -L% -l% -Wl%,$(MOZ_ICU_LIBS)) endif -+# clang 3.3 + -O2 makes jaeger crash in FixupArity -+ifdef CLANG_CXX -+ifndef MOZ_DEBUG -+Compiler.$(OBJ_SUFFIX): CXXFLAGS += -fno-inline-functions -+endif -+endif -+ - # An AIX Optimization bug causes PR_dtoa() & JS_dtoa to produce wrong result. - # This suppresses optimization for this single compilation unit. - ifeq ($(OS_ARCH),AIX) + # Prevent floating point errors caused by VC++ optimizations diff --git a/www/firefox/patches/patch-js_src_config_system-headers b/www/firefox/patches/patch-js_src_config_system-headers index 62d27f92722..d6dd1050732 100644 --- a/www/firefox/patches/patch-js_src_config_system-headers +++ b/www/firefox/patches/patch-js_src_config_system-headers @@ -1,9 +1,10 @@ -$NetBSD: patch-js_src_config_system-headers,v 1.6 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-js_src_config_system-headers,v 1.7 2014/03/20 21:02:00 ryoon Exp $ ---- js/src/config/system-headers.orig 2013-12-05 16:07:35.000000000 +0000 +--- js/src/config/system-headers.orig 2014-03-15 05:19:19.000000000 +0000 +++ js/src/config/system-headers -@@ -1144,3 +1144,4 @@ unicode/unum.h - unicode/ustring.h +@@ -1145,3 +1145,5 @@ unicode/ustring.h unicode/utypes.h #endif -+libutil.h + libutil.h ++unwind.h ++cairo-qt.h diff --git a/www/firefox/patches/patch-mb b/www/firefox/patches/patch-mb index 827d20f5468..491839768ac 100644 --- a/www/firefox/patches/patch-mb +++ b/www/firefox/patches/patch-mb @@ -1,20 +1,37 @@ -$NetBSD: patch-mb,v 1.8 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-mb,v 1.9 2014/03/20 21:02:00 ryoon Exp $ ---- xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2013-09-10 03:43:57.000000000 +0000 +--- xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2014-03-15 05:19:39.000000000 +0000 +++ xpcom/reflect/xptcall/src/md/unix/Makefile.in -@@ -183,7 +183,7 @@ endif - # - # NetBSD/PPC - # --ifneq (,$(filter NetBSDmacppc NetBSDbebox NetBSDofppc NetBSDprep NetBSDamigappc,$(OS_ARCH)$(OS_TEST))) -+ifeq ($(OS_ARCH)$(OS_TEST),NetBSDpowerpc) - ASFILES := xptcinvoke_asm_ppc_netbsd.s xptcstubs_asm_ppc_netbsd.s - endif - -@@ -235,6 +235,13 @@ ifneq (,$(filter OpenBSDsparc64 FreeBSDs - ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s - endif +@@ -83,6 +83,39 @@ endif + # SPARC + ###################################################################### # ++# Linux/SPARC ++# ++ifeq ($(OS_ARCH),Linux) ++ifneq (,$(findstring sparc,$(OS_TEST))) ++ASFILES := xptcinvoke_asm_sparc_linux_GCC3.s xptcstubs_asm_sparc_solaris.s ++endif ++endif ++# ++# NetBSD/SPARC ++# ++ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc) ++ASFILES := xptcinvoke_asm_sparc_netbsd.s xptcstubs_asm_sparc_netbsd.s ++endif ++# ++# OpenBSD/SPARC ++# ++ifeq ($(OS_ARCH)$(OS_TEST),OpenBSDsparc) ++ASFILES := xptcinvoke_asm_sparc_openbsd.s xptcstubs_asm_sparc_openbsd.s ++endif ++# ++# OpenBSD/SPARC64 ++# ++ifneq (,$(filter OpenBSDsparc64 FreeBSDsparc64,$(OS_ARCH)$(OS_TEST))) ++ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s ++endif ++# +# NetBSD/SPARC64 +# +ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc64) diff --git a/www/firefox/patches/patch-media_libtheora_Makefile.in b/www/firefox/patches/patch-media_libtheora_Makefile.in new file mode 100644 index 00000000000..b1d74312fc3 --- /dev/null +++ b/www/firefox/patches/patch-media_libtheora_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-media_libtheora_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- media/libtheora/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000 ++++ media/libtheora/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/firefox/patches/patch-media_libtremor_Makefile.in b/www/firefox/patches/patch-media_libtremor_Makefile.in new file mode 100644 index 00000000000..fb15e008cb8 --- /dev/null +++ b/www/firefox/patches/patch-media_libtremor_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-media_libtremor_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- media/libtremor/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000 ++++ media/libtremor/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/firefox/patches/patch-media_libvorbis_Makefile.in b/www/firefox/patches/patch-media_libvorbis_Makefile.in new file mode 100644 index 00000000000..2ede42f9228 --- /dev/null +++ b/www/firefox/patches/patch-media_libvorbis_Makefile.in @@ -0,0 +1,14 @@ +$NetBSD: patch-media_libvorbis_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- media/libvorbis/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000 ++++ media/libvorbis/Makefile.in +@@ -0,0 +1,9 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include $(topsrcdir)/config/rules.mk ++ ++ifdef MOZ_NATIVE_OGG ++CFLAGS += $(MOZ_OGG_CFLAGS) ++endif diff --git a/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in b/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in index 46e6c571bd6..c7f51747815 100644 --- a/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in +++ b/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in @@ -1,12 +1,25 @@ -$NetBSD: patch-media_webrtc_signaling_test_Makefile.in,v 1.4 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-media_webrtc_signaling_test_Makefile.in,v 1.5 2014/03/20 21:02:00 ryoon Exp $ ---- media/webrtc/signaling/test/Makefile.in.orig 2013-12-05 16:07:48.000000000 +0000 +--- media/webrtc/signaling/test/Makefile.in.orig 2014-03-15 05:19:29.000000000 +0000 +++ media/webrtc/signaling/test/Makefile.in -@@ -7,6 +7,7 @@ LIBS = \ - $(NSPR_LIBS) \ +@@ -8,6 +8,7 @@ LIBS = \ $(NSS_LIBS) \ $(REALTIME_LIBS) \ + $(MOZ_JS_LIBS) \ + $(MOZ_LIBV4L2_LIBS) \ $(DEPTH)/xpcom/glue/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \ $(DEPTH)/media/mtransport/standalone/$(LIB_PREFIX)mtransport_s.$(LIB_SUFFIX) \ $(DEPTH)/media/webrtc/signalingtest/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \ +@@ -40,6 +41,12 @@ LIBS += \ + $(NULL) + endif + ++ifdef MOZ_NATIVE_OPUS ++LIBS += \ ++ $(MOZ_OPUS_LIBS) \ ++ $(NULL) ++endif ++ + ifdef MOZ_NATIVE_LIBVPX + LIBS += \ + $(MOZ_LIBVPX_LIBS) \ diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi new file mode 100644 index 00000000000..da26accd9c3 --- /dev/null +++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi @@ -0,0 +1,17 @@ +$NetBSD: patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi.orig 2014-03-15 05:19:30.000000000 +0000 ++++ media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi +@@ -14,9 +14,9 @@ + 'conditions': [ + ['build_with_mozilla==1', { + # Mozilla provides its own build of the opus library. +- 'include_dirs': [ +- '$(DIST)/include/opus', +- ] ++ 'cflags_mozilla': [ ++ '$(MOZ_OPUS_CFLAGS)', ++ ], + }, { + 'dependencies': [ + '<(DEPTH)/third_party/opus/opus.gyp:opus' diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc index 529915187e6..231103c6ced 100644 --- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc +++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc @@ -1,10 +1,10 @@ -$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2013-10-25 22:27:35.000000000 +0000 +--- media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2014-03-15 05:19:30.000000000 +0000 +++ media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc -@@ -19,18 +19,30 @@ - #include <stdlib.h> - +@@ -18,17 +18,37 @@ + #include <sys/stat.h> + #include <unistd.h> //v4l includes -#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__NetBSD__) || defined(__OpenBSD__) @@ -18,9 +18,8 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__in +#include <libv4l2.h> +#endif - #include "ref_count.h" - #include "trace.h" - + #include "webrtc/system_wrappers/interface/ref_count.h" + #include "webrtc/system_wrappers/interface/trace.h" +#ifdef HAVE_LIBV4L2 +#define open v4l2_open @@ -31,10 +30,18 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__in +#define munmap v4l2_munmap +#endif + ++#ifdef HAVE_LIBV4L2 ++#define open v4l2_open ++#define close v4l2_close ++#define dup v4l2_dup ++#define ioctl v4l2_ioctl ++#define mmap v4l2_mmap ++#define munmap v4l2_munmap ++#endif + namespace webrtc { - namespace videocapturemodule -@@ -137,6 +149,11 @@ int32_t DeviceInfoLinux::GetDeviceName( +@@ -136,6 +156,11 @@ int32_t DeviceInfoLinux::GetDeviceName( memset(deviceNameUTF8, 0, deviceNameLength); memcpy(cameraName, cap.card, sizeof(cap.card)); diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc index 56f25812e3a..10847fdf84f 100644 --- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc +++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc @@ -1,9 +1,9 @@ -$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2013-10-25 22:27:35.000000000 +0000 +--- media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2014-03-15 05:19:30.000000000 +0000 +++ media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc @@ -18,13 +18,16 @@ - #include <string.h> + #include <unistd.h> //v4l includes -#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) @@ -20,9 +20,9 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__cap #include <new> -@@ -34,6 +37,15 @@ - #include "critical_section_wrapper.h" - #include "video_capture_linux.h" +@@ -34,6 +37,24 @@ + #include "webrtc/system_wrappers/interface/thread_wrapper.h" + #include "webrtc/system_wrappers/interface/trace.h" +#ifdef HAVE_LIBV4L2 +#define open v4l2_open @@ -33,6 +33,15 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__cap +#define munmap v4l2_munmap +#endif + ++#ifdef HAVE_LIBV4L2 ++#define open v4l2_open ++#define close v4l2_close ++#define dup v4l2_dup ++#define ioctl v4l2_ioctl ++#define mmap v4l2_mmap ++#define munmap v4l2_munmap ++#endif ++ namespace webrtc { namespace videocapturemodule diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp index a7c56b47a58..a2b73cec93f 100644 --- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp +++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp @@ -1,3388 +1,18 @@ -$NetBSD: patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.4 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.5 2014/03/20 21:02:00 ryoon Exp $ ---- media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2013-12-05 16:07:50.000000000 +0000 +--- media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2014-03-15 05:19:30.000000000 +0000 +++ media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp -@@ -1,1688 +1,1695 @@ --//Templated spread_sort library
--
--// Copyright Steven J. Ross 2001 - 2009.
--// 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)
--
--// See http://www.boost.org/ for updates, documentation, and revision history.
--
--/*
--Some improvements suggested by:
--Phil Endecott and Frank Gennari
--Cygwin fix provided by:
--Scott McMurray
--*/
--
--#ifndef BOOST_SPREAD_SORT_H
--#define BOOST_SPREAD_SORT_H
--#include <algorithm>
--#include <cstring>
--#include <vector>
--#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
--
--namespace boost {
-- namespace detail {
-- //This only works on unsigned data types
-- template <typename T>
-- inline unsigned
-- rough_log_2_size(const T& input)
-- {
-- unsigned result = 0;
-- //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance
-- while((input >> result) && (result < (8*sizeof(T)))) ++result;
-- return result;
-- }
--
-- //Gets the maximum size which we'll call spread_sort on to control worst-case performance
-- //Maintains both a minimum size to recurse and a check of distribution size versus count
-- //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead
-- inline size_t
-- get_max_count(unsigned log_range, size_t count)
-- {
-- unsigned divisor = rough_log_2_size(count);
-- //Making sure the divisor is positive
-- if(divisor > LOG_MEAN_BIN_SIZE)
-- divisor -= LOG_MEAN_BIN_SIZE;
-- else
-- divisor = 1;
-- unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor);
-- //Don't try to bitshift more than the size of an element
-- if((8*sizeof(size_t)) <= relative_width)
-- relative_width = (8*sizeof(size_t)) - 1;
-- return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ?
-- (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width);
-- }
--
-- //Find the minimum and maximum using <
-- template <class RandomAccessIter>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min)
-- {
-- min = max = current;
-- //Start from the second item, as max and min are initialized to the first
-- while(++current < last) {
-- if(*max < *current)
-- max = current;
-- else if(*current < *min)
-- min = current;
-- }
-- }
--
-- //Uses a user-defined comparison operator to find minimum and maximum
-- template <class RandomAccessIter, class compare>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp)
-- {
-- min = max = current;
-- while(++current < last) {
-- if(comp(*max, *current))
-- max = current;
-- else if(comp(*current, *min))
-- min = current;
-- }
-- }
--
-- //Gets a non-negative right bit shift to operate as a logarithmic divisor
-- inline int
-- get_log_divisor(size_t count, unsigned log_range)
-- {
-- int log_divisor;
-- //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so
-- if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS)
-- log_divisor = 0;
-- else {
-- //otherwise divide the data into an optimized number of pieces
-- log_divisor += LOG_MEAN_BIN_SIZE;
-- if(log_divisor < 0)
-- log_divisor = 0;
-- //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically
-- if((log_range - log_divisor) > MAX_SPLITS)
-- log_divisor = log_range - MAX_SPLITS;
-- }
-- return log_divisor;
-- }
--
-- template <class RandomAccessIter>
-- inline RandomAccessIter *
-- size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count)
-- {
-- //Assure space for the size of each bin, followed by initializing sizes
-- if(bin_count > bin_sizes.size())
-- bin_sizes.resize(bin_count);
-- for(size_t u = 0; u < bin_count; u++)
-- bin_sizes[u] = 0;
-- //Make sure there is space for the bins
-- cache_end = cache_offset + bin_count;
-- if(cache_end > bin_cache.size())
-- bin_cache.resize(cache_end);
-- return &(bin_cache[cache_offset]);
-- }
--
-- //Implementation for recursive integer sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data
-- //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- //max and min will be the same (the first item) iff all values are equivalent
-- if(max == min)
-- return;
-- RandomAccessIter * target_bin;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0)));
-- div_type div_min = *min >> log_divisor;
-- div_type div_max = *max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(*(current++) >> log_divisor) - div_min]++;
-- //Assign the bin positions
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- //This dominates runtime, mostly in the swap and bin lookups
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u) {
-- RandomAccessIter * local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((*current >> log_divisor) - div_min)) {
-- //3-way swap; this is about 1% faster than a 2-way swap with integers
-- //The main advantage is less copies are involved per item put in the correct place
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min);
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing; log_divisor is the remaining range
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Generic bitshift-based 3-way swapping code
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + (shift(*current, log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- //Note: we could increment current once the swap is done in this case, but that seems to impair performance
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- //Standard swapping wrapper for ascending values
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min);
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min, comp);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Functor implementation for recursive sorting with only Shift overridden
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned ii = 0; ii < bin_count - 1; ++ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
-- }
--
-- //Top-level sorting call for integers
-- template <class RandomAccessIter>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, *first >> 0, *first);
-- }
--
-- //integer_sort with functors
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift, compare comp) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //integer_sort with right_shift functor
-- template <class RandomAccessIter, class right_shift>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- //------------------------------------------------------ float_sort source --------------------------------------
-- //Casts a RandomAccessIter to the specified data type
-- template<class cast_type, class RandomAccessIter>
-- inline cast_type
-- cast_float_iter(const RandomAccessIter & floatiter)
-- {
-- cast_type result;
-- std::memcpy(&result, &(*floatiter), sizeof(cast_type));
-- return result;
-- }
--
-- //Casts a data element to the specified datinner_float_a type
-- template<class data_type, class cast_type>
-- inline cast_type
-- mem_cast(const data_type & data)
-- {
-- cast_type result;
-- std::memcpy(&result, &data, sizeof(cast_type));
-- return result;
-- }
--
-- namespace detail {
-- template <class RandomAccessIter, class div_type, class right_shift>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift)
-- {
-- min = max = shift(*current, 0);
-- while(++current < last) {
-- div_type value = shift(*current, 0);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Specialized swap loops for floating-point casting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min);
-- }
--
-- template <class RandomAccessIter, class cast_type>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min)
-- {
-- min = max = cast_float_iter<cast_type, RandomAccessIter>(current);
-- while(++current < last) {
-- cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Special-case sorting of positive floats with casting instead of a right_shift
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii], comp);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Casting special-case for floating-point sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min);
-- }
--
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- template <class RandomAccessIter, class cast_type, class data_type>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
-- }
--
-- //float_sort with casting
-- //The cast_type must be equal in size to the data type, and must be a signed integer
-- template <class RandomAccessIter, class cast_type>
-- inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, cVal, *first);
-- }
--
-- //float_sort with casting to an int
-- //Only use this with IEEE floating-point numbers
-- template <class RandomAccessIter>
-- inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last)
-- {
-- int cVal = 0;
-- float_sort_cast(first, last, cVal);
-- }
--
-- //float_sort with functors
-- template <class RandomAccessIter, class right_shift>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //------------------------------------------------- string_sort source ---------------------------------------------
-- namespace detail {
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter, class get_char, class get_length>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_lessthan {
-- offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() < y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_greaterthan {
-- offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() > y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class get_char, class get_length>
-- struct offset_char_lessthan {
-- offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(length(x), length(y));
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(getchar(x, u) < getchar(y, u))
-- return true;
-- else if(getchar(y, u) < getchar(x, u))
-- return false;
-- }
-- return length(x) < length(y);
-- }
-- unsigned fchar_offset;
-- get_char getchar;
-- get_length length;
-- };
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while((*first).size() <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;(*finish).size() <= char_offset; --finish) { }
-- ++finish;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, finish, char_offset);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while((*curr).size() <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while((*(--last)).size() <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(curr, last, char_offset);
-- RandomAccessIter * target_bin;
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned ii = 0; ii < last_bin; ++ii) {
-- local_bin = bins + ii;
-- nextbinstart += bin_sizes[ii + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*curr) <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while(length(*(--last)) <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, last, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - getchar((*current), char_offset)]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = end_bin - getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = end_bin - getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class unsignedchar_type>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- unsigned char unused = '\0';
-- string_sort(first, last, unused);
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class compare, class unsignedchar_type>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::reverse_string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp)
-- {
-- unsigned char unused = '\0';
-- reverse_string_sort(first, last, comp, unused);
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*(--last))) {
-- //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order
-- if(first == last)
-- return;
-- }
-- //making last just after the end of the non-empty part of the array
-- ++last;
-- detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--}
--
--#endif
-+//Templated spread_sort library -+ -+// Copyright Steven J. Ross 2001 - 2009. -+// 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) -+ -+// See http://www.boost.org/ for updates, documentation, and revision history. -+ -+/* -+Some improvements suggested by: -+Phil Endecott and Frank Gennari -+Cygwin fix provided by: -+Scott McMurray -+*/ -+ -+#ifndef BOOST_SPREAD_SORT_H -+#define BOOST_SPREAD_SORT_H -+#include <algorithm> -+#include <cstring> -+#include <vector> -+#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp" -+ -+#ifdef __FreeBSD__ -+# include <osreldate.h> -+# if __FreeBSD_version < 900506 -+# define getchar boost_getchar -+# endif -+#endif -+ -+namespace boost { -+ namespace detail { -+ //This only works on unsigned data types -+ template <typename T> -+ inline unsigned -+ rough_log_2_size(const T& input) -+ { -+ unsigned result = 0; -+ //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance -+ while((input >> result) && (result < (8*sizeof(T)))) ++result; -+ return result; -+ } -+ -+ //Gets the maximum size which we'll call spread_sort on to control worst-case performance -+ //Maintains both a minimum size to recurse and a check of distribution size versus count -+ //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead -+ inline size_t -+ get_max_count(unsigned log_range, size_t count) -+ { -+ unsigned divisor = rough_log_2_size(count); -+ //Making sure the divisor is positive -+ if(divisor > LOG_MEAN_BIN_SIZE) -+ divisor -= LOG_MEAN_BIN_SIZE; -+ else -+ divisor = 1; -+ unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor); -+ //Don't try to bitshift more than the size of an element -+ if((8*sizeof(size_t)) <= relative_width) -+ relative_width = (8*sizeof(size_t)) - 1; -+ return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ? -+ (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width); -+ } -+ -+ //Find the minimum and maximum using < -+ template <class RandomAccessIter> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min) -+ { -+ min = max = current; -+ //Start from the second item, as max and min are initialized to the first -+ while(++current < last) { -+ if(*max < *current) -+ max = current; -+ else if(*current < *min) -+ min = current; -+ } -+ } -+ -+ //Uses a user-defined comparison operator to find minimum and maximum -+ template <class RandomAccessIter, class compare> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp) -+ { -+ min = max = current; -+ while(++current < last) { -+ if(comp(*max, *current)) -+ max = current; -+ else if(comp(*current, *min)) -+ min = current; -+ } -+ } -+ -+ //Gets a non-negative right bit shift to operate as a logarithmic divisor -+ inline int -+ get_log_divisor(size_t count, unsigned log_range) -+ { -+ int log_divisor; -+ //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so -+ if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS) -+ log_divisor = 0; -+ else { -+ //otherwise divide the data into an optimized number of pieces -+ log_divisor += LOG_MEAN_BIN_SIZE; -+ if(log_divisor < 0) -+ log_divisor = 0; -+ //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically -+ if((log_range - log_divisor) > MAX_SPLITS) -+ log_divisor = log_range - MAX_SPLITS; -+ } -+ return log_divisor; -+ } -+ -+ template <class RandomAccessIter> -+ inline RandomAccessIter * -+ size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count) -+ { -+ //Assure space for the size of each bin, followed by initializing sizes -+ if(bin_count > bin_sizes.size()) -+ bin_sizes.resize(bin_count); -+ for(size_t u = 0; u < bin_count; u++) -+ bin_sizes[u] = 0; -+ //Make sure there is space for the bins -+ cache_end = cache_offset + bin_count; -+ if(cache_end > bin_cache.size()) -+ bin_cache.resize(cache_end); -+ return &(bin_cache[cache_offset]); -+ } -+ -+ //Implementation for recursive integer sorting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data -+ //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min); -+ //max and min will be the same (the first item) iff all values are equivalent -+ if(max == min) -+ return; -+ RandomAccessIter * target_bin; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0))); -+ div_type div_min = *min >> log_divisor; -+ div_type div_max = *max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(*(current++) >> log_divisor) - div_min]++; -+ //Assign the bin positions -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ //This dominates runtime, mostly in the swap and bin lookups -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) { -+ RandomAccessIter * local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + ((*current >> log_divisor) - div_min)) { -+ //3-way swap; this is about 1% faster than a 2-way swap with integers -+ //The main advantage is less copies are involved per item put in the correct place -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min); -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing; log_divisor is the remaining range -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Generic bitshift-based 3-way swapping code -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift -+ , const unsigned log_divisor, const div_type div_min) -+ { -+ RandomAccessIter * local_bin = bins + ii; -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + (shift(*current, log_divisor) - div_min)) { -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min); -+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ //Note: we could increment current once the swap is done in this case, but that seems to impair performance -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ -+ //Standard swapping wrapper for ascending values -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift -+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) -+ { -+ nextbinstart += bin_sizes[ii]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min); -+ } -+ -+ //Functor implementation for recursive sorting -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min, comp); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); -+ div_type div_min = shift(*min, log_divisor); -+ div_type div_max = shift(*max, log_divisor); -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ //Functor implementation for recursive sorting with only Shift overridden -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ RandomAccessIter max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0)))); -+ div_type div_min = shift(*min, log_divisor); -+ div_type div_max = shift(*max, log_divisor); -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned ii = 0; ii < bin_count - 1; ++ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //If we've bucketsorted, the array is sorted and we should skip recursion -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); -+ } -+ } -+ -+ //Top-level sorting call for integers -+ template <class RandomAccessIter> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::spread_sort(first, last, *first >> 0, *first); -+ } -+ -+ //integer_sort with functors -+ template <class RandomAccessIter, class right_shift, class compare> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last, -+ right_shift shift, compare comp) { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp); -+ } -+ -+ //integer_sort with right_shift functor -+ template <class RandomAccessIter, class right_shift> -+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last, -+ right_shift shift) { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::spread_sort(first, last, shift(*first, 0), *first, shift); -+ } -+ -+ //------------------------------------------------------ float_sort source -------------------------------------- -+ //Casts a RandomAccessIter to the specified data type -+ template<class cast_type, class RandomAccessIter> -+ inline cast_type -+ cast_float_iter(const RandomAccessIter & floatiter) -+ { -+ cast_type result; -+ std::memcpy(&result, &(*floatiter), sizeof(cast_type)); -+ return result; -+ } -+ -+ //Casts a data element to the specified datinner_float_a type -+ template<class data_type, class cast_type> -+ inline cast_type -+ mem_cast(const data_type & data) -+ { -+ cast_type result; -+ std::memcpy(&result, &data, sizeof(cast_type)); -+ return result; -+ } -+ -+ namespace detail { -+ template <class RandomAccessIter, class div_type, class right_shift> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift) -+ { -+ min = max = shift(*current, 0); -+ while(++current < last) { -+ div_type value = shift(*current, 0); -+ if(max < value) -+ max = value; -+ else if(value < min) -+ min = value; -+ } -+ } -+ -+ //Specialized swap loops for floating-point casting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii -+ , const unsigned log_divisor, const div_type div_min) -+ { -+ RandomAccessIter * local_bin = bins + ii; -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin; -+ target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) { -+ data_type tmp; -+ RandomAccessIter b = (*target_bin)++; -+ RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min); -+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs -+ if (b_bin != local_bin) { -+ RandomAccessIter c = (*b_bin)++; -+ tmp = *c; -+ *c = *b; -+ } -+ else -+ tmp = *b; -+ *b = *current; -+ *current = tmp; -+ } -+ } -+ *local_bin = nextbinstart; -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii -+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min) -+ { -+ nextbinstart += bin_sizes[ii]; -+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min); -+ } -+ -+ template <class RandomAccessIter, class cast_type> -+ inline void -+ find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min) -+ { -+ min = max = cast_float_iter<cast_type, RandomAccessIter>(current); -+ while(++current < last) { -+ cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current); -+ if(max < value) -+ max = value; -+ else if(value < min) -+ min = value; -+ } -+ } -+ -+ //Special-case sorting of positive floats with casting instead of a right_shift -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ bins[0] = first; -+ for(unsigned u = 0; u < bin_count - 1; u++) -+ bins[u + 1] = bins[u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count - 1; ++u) -+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min); -+ bins[bin_count - 1] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ else -+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorting negative_ float_s -+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorting negative_ float_s -+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ bins[bin_count - 1] = first; -+ for(int ii = bin_count - 2; ii >= 0; --ii) -+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //The last bin will always have the correct elements in it -+ for(int ii = bin_count - 1; ii > 0; --ii) -+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min); -+ //Since we don't process the last bin, we need to update its end position -+ bin_cache[cache_offset] = last; -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Recursing -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii], comp); -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ //Casting special-case for floating-point sorting -+ template <class RandomAccessIter, class div_type, class data_type> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min); -+ } -+ -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Functor implementation for recursive sorting -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); -+ } -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift); -+ } -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset -+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp) -+ { -+ div_type max, min; -+ find_extremes(first, last, max, min, shift); -+ if(max == min) -+ return; -+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min)); -+ div_type div_min = min >> log_divisor; -+ div_type div_max = max >> log_divisor; -+ unsigned bin_count = div_max - div_min + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); -+ -+ //Calculating the size of each bin -+ for (RandomAccessIter current = first; current != last;) -+ bin_sizes[shift(*(current++), log_divisor) - div_min]++; -+ //The index of the first positive bin -+ div_type first_positive = (div_min < 0) ? -div_min : 0; -+ //Resetting if all bins are negative -+ if(cache_offset + first_positive > cache_end) -+ first_positive = cache_end - cache_offset; -+ //Reversing the order of the negative bins -+ //Note that because of the negative/positive ordering direction flip -+ //We can not depend upon bin order and positions matching up -+ //so bin_sizes must be reused to contain the end of the bin -+ if(first_positive > 0) { -+ bins[first_positive - 1] = first; -+ for(int ii = first_positive - 2; ii >= 0; --ii) { -+ bins[ii] = first + bin_sizes[ii + 1]; -+ bin_sizes[ii] += bin_sizes[ii + 1]; -+ } -+ //Handling positives following negatives -+ if((unsigned)first_positive < bin_count) { -+ bins[first_positive] = first + bin_sizes[0]; -+ bin_sizes[first_positive] += bin_sizes[0]; -+ } -+ } -+ else -+ bins[0] = first; -+ for(unsigned u = first_positive; u < bin_count - 1; u++) { -+ bins[u + 1] = first + bin_sizes[u]; -+ bin_sizes[u + 1] += bin_sizes[u]; -+ } -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ for(unsigned u = 0; u < bin_count; ++u) { -+ nextbinstart = first + bin_sizes[u]; -+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min); -+ } -+ -+ //Return if we've completed bucketsorting -+ if(!log_divisor) -+ return; -+ -+ //Handling negative values first -+ size_t max_count = get_max_count(log_divisor, last - first); -+ RandomAccessIter lastPos = first; -+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) { -+ size_t count = bin_cache[ii] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[ii]); -+ //sort negative values using reversed-bin spread_sort -+ else -+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ -+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ if(count < 2) -+ continue; -+ if(count < max_count) -+ std::sort(lastPos, bin_cache[u]); -+ //sort positive values using normal spread_sort -+ else -+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp); -+ } -+ } -+ -+ template <class RandomAccessIter, class cast_type, class data_type> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift); -+ } -+ -+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare> -+ inline void -+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp); -+ } -+ } -+ -+ //float_sort with casting -+ //The cast_type must be equal in size to the data type, and must be a signed integer -+ template <class RandomAccessIter, class cast_type> -+ inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::float_Sort(first, last, cVal, *first); -+ } -+ -+ //float_sort with casting to an int -+ //Only use this with IEEE floating-point numbers -+ template <class RandomAccessIter> -+ inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last) -+ { -+ int cVal = 0; -+ float_sort_cast(first, last, cVal); -+ } -+ -+ //float_sort with functors -+ template <class RandomAccessIter, class right_shift> -+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::float_Sort(first, last, shift(*first, 0), *first, shift); -+ } -+ -+ template <class RandomAccessIter, class right_shift, class compare> -+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp) -+ { -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp); -+ } -+ -+ //------------------------------------------------- string_sort source --------------------------------------------- -+ namespace detail { -+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. -+ template<class RandomAccessIter> -+ inline void -+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset) -+ { -+ unsigned nextOffset = char_offset; -+ bool done = false; -+ while(!done) { -+ RandomAccessIter curr = first; -+ do { -+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character -+ if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) { -+ done = true; -+ break; -+ } -+ } while(++curr != finish); -+ if(!done) -+ ++nextOffset; -+ } -+ char_offset = nextOffset; -+ } -+ -+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance. -+ template<class RandomAccessIter, class get_char, class get_length> -+ inline void -+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length) -+ { -+ unsigned nextOffset = char_offset; -+ bool done = false; -+ while(!done) { -+ RandomAccessIter curr = first; -+ do { -+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character -+ if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) { -+ done = true; -+ break; -+ } -+ } while(++curr != finish); -+ if(!done) -+ ++nextOffset; -+ } -+ char_offset = nextOffset; -+ } -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class unsignedchar_type> -+ struct offset_lessthan { -+ offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(x.size(), y.size()); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u])) -+ return true; -+ else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u])) -+ return false; -+ } -+ return x.size() < y.size(); -+ } -+ unsigned fchar_offset; -+ }; -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class unsignedchar_type> -+ struct offset_greaterthan { -+ offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(x.size(), y.size()); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u])) -+ return true; -+ else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u])) -+ return false; -+ } -+ return x.size() > y.size(); -+ } -+ unsigned fchar_offset; -+ }; -+ -+ //A comparison functor for strings that assumes they are identical up to char_offset -+ template<class data_type, class get_char, class get_length> -+ struct offset_char_lessthan { -+ offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){} -+ inline bool operator()(const data_type &x, const data_type &y) const -+ { -+ unsigned minSize = std::min(length(x), length(y)); -+ for(unsigned u = fchar_offset; u < minSize; ++u) { -+ if(getchar(x, u) < getchar(y, u)) -+ return true; -+ else if(getchar(y, u) < getchar(x, u)) -+ return false; -+ } -+ return length(x) < length(y); -+ } -+ unsigned fchar_offset; -+ get_char getchar; -+ get_length length; -+ }; -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while((*first).size() <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;(*finish).size() <= char_offset; --finish) { } -+ ++finish; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(first, finish, char_offset); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if((*current).size() <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while((*current).size() > char_offset) { -+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; -+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset])) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1)); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //Sorts strings in reverse order, with empties at the end -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ RandomAccessIter curr = first; -+ //Iterate to the end of the empties. If all empty, return -+ while((*curr).size() <= char_offset) { -+ if(++curr == last) -+ return; -+ } -+ //Getting the last non-empty -+ while((*(--last)).size() <= char_offset) { } -+ ++last; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(curr, last, char_offset); -+ RandomAccessIter * target_bin; -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ const unsigned max_bin = bin_count - 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); -+ RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if((*current).size() <= char_offset) { -+ bin_sizes[bin_count]++; -+ } -+ else -+ bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = last; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); -+ RandomAccessIter lastFull = *local_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while((*current).size() > char_offset) { -+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ nextbinstart = first; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = max_bin; -+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin; -+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset])) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = lastFull; -+ //Recursing -+ RandomAccessIter lastPos = first; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1)); -+ else -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes); -+ } -+ } -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*first) <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;length(*finish) <= char_offset; --finish) { } -+ ++finish; -+ update_offset(first, finish, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[getchar((*current), char_offset) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = bins + getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned ii = 0; ii < last_bin; ++ii) { -+ local_bin = bins + ii; -+ nextbinstart += bin_sizes[ii + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = bins + getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1)); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length); -+ } -+ } -+ -+ //String sorting recursive implementation -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> -+ inline void -+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*first) <= char_offset) { -+ if(++first == last) -+ return; -+ } -+ RandomAccessIter finish = last - 1; -+ //Getting the last non-empty -+ for(;length(*finish) <= char_offset; --finish) { } -+ ++finish; -+ update_offset(first, finish, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[0]++; -+ } -+ else -+ bin_sizes[getchar((*current), char_offset) + 1]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = first; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]); -+ nextbinstart += bin_sizes[0]; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = bins + getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = bin_count - 1; -+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u + 1]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = bins + getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = last; -+ -+ //Recursing -+ RandomAccessIter lastPos = bin_cache[cache_offset]; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos -+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Sorts strings in reverse order, with empties at the end -+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare> -+ inline void -+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache -+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp) -+ { -+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact. -+ RandomAccessIter curr = first; -+ //Iterate to the end of the empties. If all empty, return -+ while(length(*curr) <= char_offset) { -+ if(++curr == last) -+ return; -+ } -+ //Getting the last non-empty -+ while(length(*(--last)) <= char_offset) { } -+ ++last; -+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance. -+ update_offset(first, last, char_offset, getchar, length); -+ -+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8)); -+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n). -+ const unsigned max_size = bin_count; -+ const unsigned membin_count = bin_count + 1; -+ const unsigned max_bin = bin_count - 1; -+ unsigned cache_end; -+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); -+ RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]); -+ -+ //Calculating the size of each bin; this takes roughly 10% of runtime -+ for (RandomAccessIter current = first; current != last; ++current) { -+ if(length(*current) <= char_offset) { -+ bin_sizes[bin_count]++; -+ } -+ else -+ bin_sizes[max_bin - getchar((*current), char_offset)]++; -+ } -+ //Assign the bin positions -+ bin_cache[cache_offset] = first; -+ for(unsigned u = 0; u < membin_count - 1; u++) -+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u]; -+ -+ //Swap into place -+ RandomAccessIter nextbinstart = last; -+ //handling empty bins -+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]); -+ RandomAccessIter lastFull = *local_bin; -+ RandomAccessIter * target_bin; -+ //Iterating over each element in the bin of empties -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //empties belong in this bin -+ while(length(*current) > char_offset) { -+ target_bin = end_bin - getchar((*current), char_offset); -+ iter_swap(current, (*target_bin)++); -+ } -+ } -+ *local_bin = nextbinstart; -+ nextbinstart = first; -+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops -+ unsigned last_bin = max_bin; -+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { } -+ //This dominates runtime, mostly in the swap and bin lookups -+ for(unsigned u = 0; u < last_bin; ++u) { -+ local_bin = bins + u; -+ nextbinstart += bin_sizes[u]; -+ //Iterating over each element in this bin -+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) { -+ //Swapping elements in current into place until the correct element has been swapped in -+ for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin; -+ target_bin = end_bin - getchar((*current), char_offset)) -+ iter_swap(current, (*target_bin)++); -+ } -+ *local_bin = nextbinstart; -+ } -+ bins[last_bin] = lastFull; -+ //Recursing -+ RandomAccessIter lastPos = first; -+ //Skip this loop for empties -+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) { -+ size_t count = bin_cache[u] - lastPos; -+ //don't sort unless there are at least two items to compare -+ if(count < 2) -+ continue; -+ //using std::sort if its worst-case is better -+ if(count < max_size) -+ std::sort(lastPos, bin_cache[u], comp); -+ else -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos -+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> -+ inline void -+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); -+ } -+ -+ //Holds the bin vector and makes the initial recursive call -+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type> -+ inline void -+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type) -+ { -+ std::vector<size_t> bin_sizes; -+ std::vector<RandomAccessIter> bin_cache; -+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp); -+ } -+ } -+ -+ //Allows character-type overloads -+ template <class RandomAccessIter, class unsignedchar_type> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else -+ detail::string_sort(first, last, *first, unused); -+ } -+ -+ //Top-level sorting call; wraps using default of unsigned char -+ template <class RandomAccessIter> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last) -+ { -+ unsigned char unused = '\0'; -+ string_sort(first, last, unused); -+ } -+ -+ //Allows character-type overloads -+ template <class RandomAccessIter, class compare, class unsignedchar_type> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else -+ detail::reverse_string_sort(first, last, *first, unused); -+ } -+ -+ //Top-level sorting call; wraps using default of unsigned char -+ template <class RandomAccessIter, class compare> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp) -+ { -+ unsigned char unused = '\0'; -+ reverse_string_sort(first, last, comp, unused); -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*first)) { -+ if(++first == last) -+ return; -+ } -+ detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0)); -+ } -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length, class compare> -+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*first)) { -+ if(++first == last) -+ return; -+ } -+ detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); -+ } -+ } -+ -+ template <class RandomAccessIter, class get_char, class get_length, class compare> -+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp) -+ { -+ //Don't sort if it's too small to optimize -+ if(last - first < detail::MIN_SORT_SIZE) -+ std::sort(first, last, comp); -+ else { -+ //skipping past empties at the beginning, which allows us to get the character type -+ //.empty() is not used so as not to require a user declaration of it -+ while(!length(*(--last))) { -+ //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order -+ if(first == last) -+ return; -+ } -+ //making last just after the end of the non-empty part of the array -+ ++last; -+ detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0)); -+ } -+ } -+} -+ -+#endif +@@ -21,6 +21,13 @@ Scott McMurray
+ #include <vector>
+ #include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
+
++#ifdef __FreeBSD__
++# include <osreldate.h>
++# if __FreeBSD_version < 900506
++# define getchar boost_getchar
++# endif
++#endif
++
+ namespace boost {
+ namespace detail {
+ //This only works on unsigned data types
diff --git a/www/firefox/patches/patch-memory_jemalloc_Makefile.in b/www/firefox/patches/patch-memory_jemalloc_Makefile.in new file mode 100644 index 00000000000..3866d1139cb --- /dev/null +++ b/www/firefox/patches/patch-memory_jemalloc_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-memory_jemalloc_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- memory/jemalloc/Makefile.in.orig 2014-03-15 05:19:31.000000000 +0000 ++++ memory/jemalloc/Makefile.in +@@ -21,3 +21,7 @@ endif + ifdef GNU_CC + CFLAGS += -std=gnu99 + endif ++ ++# XXX startup crash workaround for gcc47 on amd64 ++jemalloc.$(OBJ_SUFFIX): OS_CFLAGS := $(filter-out -O3 -Ofast,$(OS_CFLAGS)) ++jemalloc.$(OBJ_SUFFIX): MOZ_OPTIMIZE_FLAGS= diff --git a/www/firefox/patches/patch-netwerk_dns_Makefile.in b/www/firefox/patches/patch-netwerk_dns_Makefile.in new file mode 100644 index 00000000000..61579517fc4 --- /dev/null +++ b/www/firefox/patches/patch-netwerk_dns_Makefile.in @@ -0,0 +1,12 @@ +$NetBSD: patch-netwerk_dns_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- netwerk/dns/Makefile.in.orig 2014-03-15 05:19:32.000000000 +0000 ++++ netwerk/dns/Makefile.in +@@ -9,3 +9,7 @@ include $(topsrcdir)/config/rules.mk + # for effective TLD data. + etld_data.inc: $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat + $(PYTHON) $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat > etld_data.inc ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++nsIDNService.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS) ++endif diff --git a/www/firefox/patches/patch-netwerk_wifi_moz.build b/www/firefox/patches/patch-netwerk_wifi_moz.build index 6445bbc1a07..9a7758f7ed0 100644 --- a/www/firefox/patches/patch-netwerk_wifi_moz.build +++ b/www/firefox/patches/patch-netwerk_wifi_moz.build @@ -1,15 +1,15 @@ -$NetBSD: patch-netwerk_wifi_moz.build,v 1.5 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-netwerk_wifi_moz.build,v 1.6 2014/03/20 21:02:00 ryoon Exp $ ---- netwerk/wifi/moz.build.orig 2014-02-12 21:29:17.000000000 +0000 +--- netwerk/wifi/moz.build.orig 2014-03-15 05:19:33.000000000 +0000 +++ netwerk/wifi/moz.build -@@ -38,6 +38,10 @@ if CONFIG['OS_ARCH'] == 'Darwin': - SOURCES += [ +@@ -35,6 +35,10 @@ if CONFIG['OS_ARCH'] == 'Darwin': + UNIFIED_SOURCES += [ 'osx_corewlan.mm', ] +elif CONFIG['OS_ARCH'] == 'FreeBSD': -+ CPP_SOURCES += [ ++ UNIFIED_SOURCES += [ + 'nsWifiScannerFreeBSD.cpp', + ] elif CONFIG['OS_ARCH'] == 'WINNT': - SOURCES += [ + UNIFIED_SOURCES += [ 'nsWifiScannerWin.cpp', diff --git a/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp b/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp index 5c6f323114c..c22f84d1c30 100644 --- a/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp +++ b/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp @@ -1,8 +1,8 @@ -$NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.4 2014/03/20 21:02:00 ryoon Exp $ ---- netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2013-09-14 15:17:47.000000000 +0000 +--- netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2014-03-20 11:09:40.000000000 +0000 +++ netwerk/wifi/nsWifiScannerFreeBSD.cpp -@@ -0,0 +1,172 @@ +@@ -0,0 +1,167 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -31,43 +31,39 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r +static nsresult +FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints) +{ -+ bool res = false; -+ char *dupn = NULL; -+ struct ifaddrs *ifal, *ifa; -+ unsigned len; -+ + // get list of interfaces -+ if (getifaddrs(&ifal) < 0) ++ struct ifaddrs *ifal; ++ if (getifaddrs(&ifal) < 0) { + return NS_ERROR_FAILURE; ++ } + + accessPoints.Clear(); + + // loop through the interfaces ++ nsresult rv = NS_ERROR_FAILURE; ++ struct ifaddrs *ifa; + for (ifa = ifal; ifa; ifa = ifa->ifa_next) { -+ int s; -+ struct ifreq ifr; -+ struct ifmediareq ifmr; -+ struct ieee80211req i802r; -+ char iscanbuf[32*1024], *vsr; -+ -+ memset(&ifr, 0, sizeof(ifr)); -+ -+ // list can contain duplicates, so ignore those -+ if (dupn != NULL && strcmp(dupn, ifa->ifa_name) == 0) ++ // limit to one interface per address ++ if (ifa->ifa_addr->sa_family != AF_LINK) { + continue; -+ dupn = ifa->ifa_name; ++ } + + // store interface name in socket structure ++ struct ifreq ifr; ++ memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); + ifr.ifr_addr.sa_family = AF_LOCAL; + + // open socket to interface -+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) ++ int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); ++ if (s < 0) { + continue; ++ } + + // clear interface media structure -+ (void) memset(&ifmr, 0, sizeof(ifmr)); -+ (void) strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name)); ++ struct ifmediareq ifmr; ++ memset(&ifmr, 0, sizeof(ifmr)); ++ strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name)); + + // get interface media information + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { @@ -82,8 +78,10 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r + } + + // perform WiFi scan -+ (void) memset(&i802r, 0, sizeof(i802r)); -+ (void) strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name)); ++ struct ieee80211req i802r; ++ char iscanbuf[32*1024]; ++ memset(&i802r, 0, sizeof(i802r)); ++ strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name)); + i802r.i_type = IEEE80211_IOC_SCAN_RESULTS; + i802r.i_data = iscanbuf; + i802r.i_len = sizeof(iscanbuf); @@ -96,36 +94,33 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r + close(s); + + // loop through WiFi networks and build geoloc-lookup structure -+ vsr = (char *) i802r.i_data; -+ len = i802r.i_len; ++ char *vsr = (char *) i802r.i_data; ++ unsigned len = i802r.i_len; + while (len >= sizeof(struct ieee80211req_scan_result)) { -+ struct ieee80211req_scan_result *isr; -+ char *id; -+ int idlen; -+ char ssid[IEEE80211_NWID_LEN+1]; -+ nsWifiAccessPoint *ap; -+ -+ isr = (struct ieee80211req_scan_result *) vsr; ++ struct ieee80211req_scan_result *isr = ++ (struct ieee80211req_scan_result *) vsr; + + // determine size of this entry ++ char *id; ++ int idlen; + if (isr->isr_meshid_len) { + id = vsr + isr->isr_ie_off + isr->isr_ssid_len; + idlen = isr->isr_meshid_len; -+ } -+ else { ++ } else { + id = vsr + isr->isr_ie_off; + idlen = isr->isr_ssid_len; + } + + // copy network data ++ char ssid[IEEE80211_NWID_LEN+1]; + strncpy(ssid, id, idlen); + ssid[idlen] = '\0'; -+ ap = new nsWifiAccessPoint(); ++ nsWifiAccessPoint *ap = new nsWifiAccessPoint(); + ap->setSSID(ssid, strlen(ssid)); + ap->setMac(isr->isr_bssid); + ap->setSignal(isr->isr_rssi); + accessPoints.AppendObject(ap); -+ res = true; ++ rv = NS_OK; + + // log the data + LOG(( "FreeBSD access point: " @@ -143,7 +138,7 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r + + freeifaddrs(ifal); + -+ return res ? NS_OK : NS_ERROR_FAILURE; ++ return rv; +} + +nsresult diff --git a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm new file mode 100644 index 00000000000..0484c0e325f --- /dev/null +++ b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm @@ -0,0 +1,13 @@ +$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- toolkit/components/osfile/modules/osfile_unix_allthreads.jsm.orig 2014-03-15 05:19:36.000000000 +0000 ++++ toolkit/components/osfile/modules/osfile_unix_allthreads.jsm +@@ -41,7 +41,7 @@ let Const = SharedAll.Constants.libc; + // Open libc + let libc; + let libc_candidates = [ "libSystem.B.dylib", +- "libc.so.6", ++ "libc.so.7", + "libc.so" ]; + for (let i = 0; i < libc_candidates.length; ++i) { + try { diff --git a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm index 25b786955ee..3440a9762dd 100644 --- a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm +++ b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm @@ -1,61 +1,33 @@ -$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.4 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.5 2014/03/20 21:02:00 ryoon Exp $ Based on martin@'s patch for firefox 27.0 * Use off_t for st_size * Use function name for NetBSD ---- toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2014-02-12 21:29:22.000000000 +0000 +--- toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2014-03-15 05:19:36.000000000 +0000 +++ toolkit/components/osfile/modules/osfile_unix_back.jsm -@@ -380,9 +380,15 @@ - /*oflags*/Type.int, - /*mode*/ Type.int); - -+ if (OS.Constants.Sys.Name == "NetBSD") { -+ declareLazyFFI(SysFile, "opendir", libc, "__opendir30", ctypes.default_abi, -+ /*return*/ Type.null_or_DIR_ptr, -+ /*path*/ Type.path); -+ } else { - declareLazyFFI(SysFile, "opendir", libc, "opendir", ctypes.default_abi, - /*return*/ Type.null_or_DIR_ptr, - /*path*/ Type.path); -+ } - - declareLazyFFI(SysFile, "pread", libc, "pread", ctypes.default_abi, - /*return*/ Type.negativeone_or_ssize_t, -@@ -419,6 +425,10 @@ - declareLazyFFI(SysFile, "readdir", libc, "readdir$INODE64", ctypes.default_abi, - /*return*/Type.null_or_dirent_ptr, - /*dir*/ Type.DIR.in_ptr); // For MacOS X -+ } else if (OS.Constants.Sys.Name == "NetBSD") { -+ declareLazyFFI(SysFile, "readdir", libc, "__readdir30", ctypes.default_abi, -+ /*return*/Type.null_or_dirent_ptr, -+ /*dir*/ Type.DIR.in_ptr); - } else { - declareLazyFFI(SysFile, "readdir", libc, "readdir", ctypes.default_abi, - /*return*/Type.null_or_dirent_ptr, -@@ -529,6 +539,24 @@ - SysFile.fstat = function fstat(fd, buf) { +@@ -558,18 +558,19 @@ return Stat.fxstat(ver, fd, buf); }; -+ } else if (OS.Constants.Sys.Name == "NetBSD") { + } else if (OS.Constants.Sys.Name == "NetBSD") { +- // NetBSD 5.0 and newer +- declareLazyFFI(SysFile, "stat", libc, "__stat50", ctypes.default_abi, + // NetBSD 5.0 uses *30, and netbsd-6 uses *50 + let v = OS.Constants.libc.OSFILE_SIZEOF_TIME_T < 8 ? "30" : "50"; + declareLazyFFI(SysFile, "stat", libc, "__stat"+v, ctypes.default_abi, -+ /*return*/ Type.negativeone_or_nothing, -+ /*path*/ Type.path, -+ /*buf*/ Type.stat.out_ptr -+ ); + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); +- declareLazyFFI(SysFile, "lstat", libc, "__lstat50", ctypes.default_abi, + declareLazyFFI(SysFile, "lstat", libc, "__lstat"+v, ctypes.default_abi, -+ /*return*/ Type.negativeone_or_nothing, -+ /*path*/ Type.path, -+ /*buf*/ Type.stat.out_ptr -+ ); + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); +- declareLazyFFI(SysFile, "fstat", libc, "__fstat50", ctypes.default_abi, + declareLazyFFI(SysFile, "fstat", libc, "__fstat"+v, ctypes.default_abi, -+ /*return*/ Type.negativeone_or_nothing, -+ /*fd*/ Type.fd, -+ /*buf*/ Type.stat.out_ptr -+ ); - } else { - // Mac OS X 32-bits, other Unix - declareLazyFFI(SysFile, "stat", libc, "stat", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*fd*/ Type.fd, + /*buf*/ Type.stat.out_ptr diff --git a/www/firefox/patches/patch-toolkit_library_Makefile.in b/www/firefox/patches/patch-toolkit_library_Makefile.in index ad7ba8d21f9..38c60e0f543 100644 --- a/www/firefox/patches/patch-toolkit_library_Makefile.in +++ b/www/firefox/patches/patch-toolkit_library_Makefile.in @@ -1,23 +1,46 @@ -$NetBSD: patch-toolkit_library_Makefile.in,v 1.4 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-toolkit_library_Makefile.in,v 1.5 2014/03/20 21:02:00 ryoon Exp $ ---- toolkit/library/Makefile.in.orig 2014-02-12 21:29:23.000000000 +0000 +--- toolkit/library/Makefile.in.orig 2014-03-15 05:19:37.000000000 +0000 +++ toolkit/library/Makefile.in -@@ -407,6 +407,7 @@ endif - EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib) +@@ -164,6 +164,18 @@ ifdef MOZ_NATIVE_HUNSPELL + EXTRA_DSO_LDOPTS += $(MOZ_HUNSPELL_LIBS) + endif - ifdef MOZ_WEBRTC -+EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS) - ifdef MOZ_PEERCONNECTION - COMPONENT_LIBS += peerconnection ++ifdef MOZ_NATIVE_OGG ++EXTRA_DSO_LDOPTS += $(MOZ_OGG_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_VORBIS ++EXTRA_DSO_LDOPTS += $(MOZ_VORBIS_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_OPUS ++EXTRA_DSO_LDOPTS += $(MOZ_OPUS_LIBS) ++endif ++ + ifdef MOZ_NATIVE_LIBEVENT + EXTRA_DSO_LDOPTS += $(MOZ_LIBEVENT_LIBS) endif -@@ -552,6 +553,10 @@ OS_LIBS += $(call EXPAND_LIBNAME,kvm) - EXTRA_DSO_LDOPTS += -Wl,--warn-unresolved-symbols +@@ -176,6 +188,14 @@ ifndef MOZ_TREE_PIXMAN + EXTRA_DSO_LDOPTS += $(MOZ_PIXMAN_LIBS) endif -+ifeq ($(OS_ARCH),FreeBSD) -+OS_LIBS += $(call EXPAND_LIBNAME,util) ++ifdef MOZ_NATIVE_GRAPHITE2 ++EXTRA_DSO_LDOPTS += $(MOZ_GRAPHITE2_LIBS) ++endif ++ ++ifdef MOZ_NATIVE_HARFBUZZ ++EXTRA_DSO_LDOPTS += $(MOZ_HARFBUZZ_LIBS) +endif + - ifeq ($(OS_ARCH),WINNT) - OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 version winspool comdlg32 imm32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg iphlpapi uxtheme setupapi secur32 sensorsapi portabledeviceguids windowscodecs wininet wbemuuid) - ifdef ACCESSIBILITY + ifdef MOZ_DMD + EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,dmd,$(DIST)/lib) + endif +@@ -183,6 +203,7 @@ endif + EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib) + + ifdef MOZ_WEBRTC ++EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS) + ifdef MOZ_WEBRTC_SIGNALING + SHARED_LIBRARY_LIBS += \ + $(DEPTH)/media/webrtc/signaling/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \ diff --git a/www/firefox/patches/patch-toolkit_xre_Makefile.in b/www/firefox/patches/patch-toolkit_xre_Makefile.in deleted file mode 100644 index faa15117e87..00000000000 --- a/www/firefox/patches/patch-toolkit_xre_Makefile.in +++ /dev/null @@ -1,10 +0,0 @@ -$NetBSD: patch-toolkit_xre_Makefile.in,v 1.3 2014/02/20 13:19:03 ryoon Exp $ - ---- toolkit/xre/Makefile.in.orig 2013-09-10 03:43:56.000000000 +0000 -+++ toolkit/xre/Makefile.in -@@ -216,5 +216,3 @@ GARBAGE += platform.ini - libs:: platform.ini - $(INSTALL) $^ $(DIST)/bin - --install:: -- $(INSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir) diff --git a/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp b/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp deleted file mode 100644 index 05e91e98444..00000000000 --- a/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp +++ /dev/null @@ -1,31 +0,0 @@ -$NetBSD: patch-xpcom_base_nsMemoryInfoDumper.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ - ---- xpcom/base/nsMemoryInfoDumper.cpp.orig 2013-12-05 16:08:00.000000000 +0000 -+++ xpcom/base/nsMemoryInfoDumper.cpp -@@ -30,7 +30,7 @@ - #include <unistd.h> - #endif - --#ifdef XP_LINUX -+#if defined(XP_LINUX) || defined(__FreeBSD__) - #include <fcntl.h> - #include <sys/types.h> - #include <sys/stat.h> -@@ -109,7 +109,7 @@ private: - - } // anonymous namespace - --#ifdef XP_LINUX // { -+#if defined(XP_LINUX) || defined(__FreeBSD__) // { - namespace { - - /* -@@ -548,7 +548,7 @@ nsMemoryInfoDumper::~nsMemoryInfoDumper( - /* static */ void - nsMemoryInfoDumper::Initialize() - { --#ifdef XP_LINUX -+#if defined(XP_LINUX) || defined(__FreeBSD__) - SignalPipeWatcher::Create(); - FifoWatcher::MaybeCreate(); - #endif diff --git a/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp b/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp deleted file mode 100644 index e5091575c76..00000000000 --- a/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp +++ /dev/null @@ -1,106 +0,0 @@ -$NetBSD: patch-xpcom_base_nsMemoryReporterManager.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ - ---- xpcom/base/nsMemoryReporterManager.cpp.orig 2014-02-12 21:29:26.000000000 +0000 -+++ xpcom/base/nsMemoryReporterManager.cpp -@@ -201,6 +201,43 @@ ResidentFastDistinguishedAmount(int64_t* - return ResidentDistinguishedAmount(aN); - } - -+#ifdef __FreeBSD__ -+#include <libutil.h> -+ -+static nsresult -+GetKinfoVmentrySelf(int64_t* prss) -+{ -+ int cnt; -+ struct kinfo_vmentry *vmmap, *kve; -+ if ((vmmap = kinfo_getvmmap(getpid(), &cnt)) == NULL) -+ return NS_ERROR_FAILURE; -+ -+ if (prss) -+ *prss = 0; -+ -+ for (int i = 0; i < cnt; i++) { -+ kve = &vmmap[i]; -+ if (prss) -+ *prss += kve->kve_private_resident; -+ } -+ -+ free(vmmap); -+ return NS_OK; -+} -+ -+#define HAVE_PRIVATE_REPORTER -+static nsresult -+GetPrivate(int64_t* aN) -+{ -+ int64_t priv; -+ nsresult rv = GetKinfoVmentrySelf(&priv); -+ if (NS_SUCCEEDED(rv)) -+ *aN = priv * getpagesize(); -+ -+ return NS_OK; -+} -+#endif // FreeBSD -+ - #elif defined(SOLARIS) - - #include <procfs.h> -@@ -428,6 +465,24 @@ public: - }; - - #define HAVE_PRIVATE_REPORTER -+static nsresult -+GetPrivate(int64_t* aN) -+{ -+ PROCESS_MEMORY_COUNTERS_EX pmcex; -+ pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX); -+ -+ if (!GetProcessMemoryInfo( -+ GetCurrentProcess(), -+ (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) { -+ return NS_ERROR_FAILURE; -+ } -+ -+ *aN = pmcex.PrivateUsage; -+ return NS_OK; -+} -+#endif // XP_<PLATFORM> -+ -+#ifdef HAVE_PRIVATE_REPORTER - class PrivateReporter MOZ_FINAL : public MemoryUniReporter - { - public: -@@ -440,21 +495,10 @@ public: - - NS_IMETHOD GetAmount(int64_t* aAmount) - { -- PROCESS_MEMORY_COUNTERS_EX pmcex; -- pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX); -- -- if (!GetProcessMemoryInfo( -- GetCurrentProcess(), -- (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) { -- return NS_ERROR_FAILURE; -- } -- -- *aAmount = pmcex.PrivateUsage; -- return NS_OK; -+ return GetPrivate(aAmount); - } - }; -- --#endif // XP_<PLATFORM> -+#endif - - #ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS - class VsizeReporter MOZ_FINAL : public MemoryUniReporter -@@ -842,7 +886,7 @@ nsMemoryReporterManager::Init() - RegisterReporter(new mozilla::dmd::DMDReporter); - #endif - --#if defined(XP_LINUX) -+#if defined(XP_LINUX) || defined(__FreeBSD__) - nsMemoryInfoDumper::Initialize(); - #endif - diff --git a/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp b/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp index ac07762d6c1..1d877e7db6f 100644 --- a/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp +++ b/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp @@ -1,8 +1,21 @@ -$NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.4 2014/03/20 21:02:00 ryoon Exp $ ---- xpcom/base/nsStackWalk.cpp.orig 2013-05-11 19:19:56.000000000 +0000 +--- xpcom/base/nsStackWalk.cpp.orig 2014-03-15 05:19:39.000000000 +0000 +++ xpcom/base/nsStackWalk.cpp -@@ -853,7 +853,7 @@ void DemangleSymbol(const char * aSymbol +@@ -23,6 +23,12 @@ struct CriticalAddress { + }; + static CriticalAddress gCriticalAddress; + ++// for _Unwind_Backtrace from libcxxrt or libunwind ++// cxxabi.h from libcxxrt implicitly includes unwind.h first ++#if defined(HAVE__UNWIND_BACKTRACE) && !defined(_GNU_SOURCE) ++#define _GNU_SOURCE ++#endif ++ + #if defined(HAVE_DLOPEN) || defined(XP_MACOSX) + #include <dlfcn.h> + #endif +@@ -874,7 +880,7 @@ void DemangleSymbol(const char * aSymbol } @@ -11,3 +24,13 @@ $NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $ /* * Stack walking code for Solaris courtesy of Bart Smaalder's "memtrak". +@@ -1223,9 +1229,6 @@ NS_StackWalk(NS_WalkStackCallback aCallb + #elif defined(HAVE__UNWIND_BACKTRACE) + + // libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0 +-#ifndef _GNU_SOURCE +-#define _GNU_SOURCE +-#endif + #include <unwind.h> + + struct unwind_info { diff --git a/www/firefox/patches/patch-xpcom_base_nscore.h b/www/firefox/patches/patch-xpcom_base_nscore.h new file mode 100644 index 00000000000..b3c515a227d --- /dev/null +++ b/www/firefox/patches/patch-xpcom_base_nscore.h @@ -0,0 +1,13 @@ +$NetBSD: patch-xpcom_base_nscore.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- xpcom/base/nscore.h.orig 2014-03-15 05:19:39.000000000 +0000 ++++ xpcom/base/nscore.h +@@ -110,7 +110,7 @@ + * NS_HIDDEN_(int) NS_FASTCALL func2(char *foo); + */ + +-#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2) ++#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2) && !(defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ == 0) + #define NS_FASTCALL __attribute__ ((regparm (3), stdcall)) + #define NS_CONSTRUCTOR_FASTCALL __attribute__ ((regparm (3), stdcall)) + #elif defined(XP_WIN) && !defined(_WIN64) diff --git a/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp b/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp new file mode 100644 index 00000000000..52e4acf2f88 --- /dev/null +++ b/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp @@ -0,0 +1,13 @@ +$NetBSD: patch-xpcom_io_nsLocalFileUnix.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $ + +--- xpcom/io/nsLocalFileUnix.cpp.orig 2014-03-15 05:19:39.000000000 +0000 ++++ xpcom/io/nsLocalFileUnix.cpp +@@ -382,7 +382,7 @@ nsLocalFile::OpenNSPRFileDesc(int32_t fl + PR_Delete(mPath.get()); + } + +-#if defined(LINUX) && !defined(ANDROID) ++#if defined(HAVE_POSIX_FADVISE) + if (flags & OS_READAHEAD) { + posix_fadvise(PR_FileDesc2NativeHandle(*_retval), 0, 0, + POSIX_FADV_SEQUENTIAL); diff --git a/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build index 125358e5e43..9230f7f5c7b 100644 --- a/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build +++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build @@ -1,12 +1,12 @@ -$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.4 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.5 2014/03/20 21:02:00 ryoon Exp $ * Support NetBSD/amd64 and DragonFly/amd64. ---- xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2014-02-12 21:29:26.000000000 +0000 +--- xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2014-03-15 05:19:39.000000000 +0000 +++ xpcom/reflect/xptcall/src/md/unix/moz.build -@@ -12,14 +12,14 @@ if CONFIG['OS_ARCH'] == 'Darwin': - 'xptcstubs_darwin.cpp', - ] +@@ -19,14 +19,14 @@ if CONFIG['OS_ARCH'] == 'Darwin': + if '86' in CONFIG['OS_TEST'] and CONFIG['OS_TEST'] != 'x86_64': + DEFINES['MOZ_NEED_LEADING_UNDERSCORE'] = True -if CONFIG['OS_ARCH'] in ('NetBSD', 'OpenBSD', 'GNU'): +if CONFIG['OS_ARCH'] in ('OpenBSD', 'GNU'): diff --git a/www/firefox/patches/patch-xn b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S index 14337f2dd70..c897f719e43 100644 --- a/www/firefox/patches/patch-xn +++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S @@ -1,7 +1,7 @@ -$NetBSD: patch-xn,v 1.3 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S,v 1.1 2014/03/20 21:02:00 ryoon Exp $ ---- xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s.orig 2013-01-04 23:44:47.000000000 +0000 -+++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s +--- xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S.orig 2014-03-15 05:19:39.000000000 +0000 ++++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S @@ -16,6 +16,47 @@ #include <sys/asm.h> #endif diff --git a/www/firefox/patches/patch-xo b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S index 49691c084fd..574949c7757 100644 --- a/www/firefox/patches/patch-xo +++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S @@ -1,7 +1,7 @@ -$NetBSD: patch-xo,v 1.3 2014/02/20 13:19:03 ryoon Exp $ +$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S,v 1.1 2014/03/20 21:02:00 ryoon Exp $ ---- xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.orig 2013-01-04 23:44:47.000000000 +0000 -+++ xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s +--- xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S.orig 2014-03-15 05:19:39.000000000 +0000 ++++ xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S @@ -14,6 +14,47 @@ #include <sys/asm.h> #endif |