Compare commits

...

134 Commits

Author SHA1 Message Date
zzz
26a9e8bd89 0.9.28 2016-12-12 16:08:35 +00:00
zzz
f5e8220c8b add java version to manifest 2016-12-12 15:59:10 +00:00
zzz
b7c7e02518 remove reseed serving old files 2016-12-12 15:58:33 +00:00
zzz
7eadc3df6f restore two sites up again 2016-12-12 15:57:58 +00:00
zzz
2f3f01c5c7 remove git.repo.i2p 2016-12-09 20:13:36 +00:00
zzz
5d7546598e remove zerobin 2016-12-09 16:01:23 +00:00
zzz
434e3badd6 translation updates 2016-12-09 15:58:22 +00:00
zzz
541e9e6dc0 Remove DOS line endings in cert (fails ant testscripts) 2016-12-09 15:52:37 +00:00
zzz
8a3a725730 GeoIP: Update from Maxmind 2016-12-06 2016-12-06 19:10:25 +00:00
zzz
74cd5cee20 Router: Revert default family sig type back to ECDSA,
as the OIDs are changing, to be deferred to next release.
Update blocklist
2016-12-05 13:41:51 +00:00
zzz
f461d4881d javadoc fixes 2016-12-03 14:27:50 +00:00
zzz
5be077e25d Clean up single char indexOf() 2016-12-02 18:52:37 +00:00
zzz
5b31540fe8 Console: Version the css links 2016-12-02 17:23:02 +00:00
zzz
ec94a6eca3 NetDb: Peer selection tweaks 2016-12-01 14:33:26 +00:00
zzz
04321e6af3 remove jump server 2016-12-01 14:29:02 +00:00
zzz
25fd488db0 Blocklist: Read feed file before user-specified file 2016-11-27 15:58:57 +00:00
zzz
850f1504f7 NetDb: Add MTU, SSU caps, IPv6 prefix, and cost lookups 2016-11-27 15:46:07 +00:00
zzz
2318a2b319 NetDb: Add same-port check in peer selector
Convert FloodfillPeerSelector MaskedIPSet to use the one now in util
2016-11-27 14:58:34 +00:00
zzz
8d494ad162 Lookup by port and sig type 2016-11-26 17:43:18 +00:00
zzz
5a87c232ea NetDb: Add advanced lookup form
Fix /16 and /8 lookup
Fix tab highlighted for all lookups
Add sybil points for banlist
2016-11-26 15:11:06 +00:00
zzz
f6778c573a SU3File: Add types for blocklist (proposal #130) 2016-11-25 14:53:42 +00:00
zzz
ffb3a75813 add converttohash to commandline 2016-11-25 14:06:23 +00:00
zzz
e3435dce10 sybil tweaks 2016-11-25 13:54:17 +00:00
zzz
497d08845c add links 2016-11-24 18:12:18 +00:00
zzz
cc6cd9e402 Sybil tool enhancements 2016-11-24 18:04:40 +00:00
zzz
64f5fed05a blocklist feed tweaks 2016-11-24 13:54:54 +00:00
zzz
1d280156a2 Console: Lookup RI by IP with netmask 2016-11-23 18:08:15 +00:00
zzz
08f7e5d6a8 ip links 2016-11-23 17:08:13 +00:00
zzz
b72b768945 Console: Lookup RI by IP 2016-11-23 16:13:07 +00:00
zzz
89733251d4 Console: Lookup RI by caps
stub out lookup by IP
2016-11-23 16:00:36 +00:00
zzz
8146f6fdb6 FFPeerSelector: Penalize new and slow peers 2016-11-23 14:21:57 +00:00
zzz
625e992c91 News: Add command line support 2016-11-23 14:06:33 +00:00
zzz
62064da081 News: Support blocklist in the news feed (proposal 129) 2016-11-23 13:54:05 +00:00
zzz
86c0fe327b NetDB: Fix detection of bandwidth class when multiple values are specified 2016-11-21 21:03:37 +00:00
zzz
bbb921806e NetDB: When doing lookups, don't use floodfills too close 2016-11-20 22:25:00 +00:00
zzz
fdff5ecd43 Router: Change default family sig type to EdDSA 2016-11-20 16:32:38 +00:00
zzz
97af7d0622 margins on /configlogging 2016-11-20 15:43:16 +00:00
str4d
11579b9818 merge of '8bf9850eb3fe4fcfb63053838a188969b7ba9c5b'
and 'a40ea9b5f7545281195f00a80e31ae879197e76b'
2016-11-20 06:08:40 +00:00
str4d
01cfb7b241 merge of '348832602d6528cc162d427742d0910df3db76ef'
and 'd51aa134c2f1b0fe533f79663f1e79dade41bde1'
2016-11-20 06:07:00 +00:00
zzz
b0bba18f33 Build: Add manifest attributes for java version to all jars and wars 2016-11-17 15:14:50 +00:00
zzz
70902bd279 Tomcat 6.0.48 2016-11-17 14:56:52 +00:00
zzz
cd4d5a39bf Console: Add netdb lookup by family 2016-11-17 14:33:33 +00:00
zzz
7a1a1d5b93 NetDB: When verifying store, don't use floodfills too close
to the store
2016-11-17 14:27:55 +00:00
zzz
66c2664b91 Blocklist: Add support for IPv6 in blocklist.txt
fixup main() test, minor cleanups
2016-11-17 13:45:36 +00:00
zzz
68e5fd6d08 Profiles: Pull same-IP detection into a utility class, for use by netdb 2016-11-16 18:05:40 +00:00
zzz
37d3204e43 Router: Add methods to verify and track members of our family;
use on sybil page
2016-11-16 18:01:24 +00:00
zzz
784566a7cb eddsa findbugs 2016-11-16 15:27:28 +00:00
zzz
126850626c socks findbugs 2016-11-16 15:26:19 +00:00
zzz
42cbc1e9ac Console: Remove dead home page links 2016-11-16 12:34:24 +00:00
zzz
1a46d9373d Certs: Add Let's Encrypt ISRG Root X1 cert 2016-11-15 20:17:32 +00:00
zzz
cd5d5ee23d Logs: Fix output of dup message after 30 minutes 2016-11-14 13:15:36 +00:00
zzz
16a551f7ce UPnP: Prevent NPE on socket creation fail (ticket #1681) 2016-11-13 16:30:51 +00:00
zzz
75d599e061 Handle case where it was an emptyList 2016-11-13 16:11:19 +00:00
zzz
efd953f3d4 Console: Add initial news to bottom of news page so it doesn't disappear (ticket #1153) 2016-11-13 15:56:47 +00:00
zzz
3ac8e5f54f UPnP: Prevent exception on bad HTTP header (ticket #1480) 2016-11-13 15:11:59 +00:00
zzz
0108c1c290 i2psnark: Periodically DHT nodes (ticket #1328) 2016-11-13 13:48:38 +00:00
zzz
a8976d25e3 Profiles: Delete old ones after saving (ticket #1328) 2016-11-12 23:10:55 +00:00
zzz
6a72c2957b Profiles: Periodically save (ticket #1328) 2016-11-12 22:27:34 +00:00
zzz
f69c0998ea Susimail: Fix nonce error on login after logout
Fix internal error after cancel button on settings form when not logged in
2016-11-12 20:10:58 +00:00
zzz
35548ff9be Susimail: Add logout button to more pages (ticket #1374) 2016-11-12 19:43:00 +00:00
zzz
6ed329db78 I2CP: Reduce log level of error when session closed
while signing leaseset (ticket #1606)
2016-11-12 18:07:20 +00:00
zzz
2c65173bec Console: Add IPv6 firewalled setting on /confignet 2016-11-12 15:14:43 +00:00
zzz
6acc23af00 Console: Fix inadvertent config save when clicking restart or shutdown
on /configstats
2016-11-12 14:54:56 +00:00
zzz
d7a84c88cd JRobin: Move DeallocationHelper logging from wrapper log to router log
Fix redundant cast
2016-11-12 12:29:30 +00:00
zzz
aeeee0e5c4 Build: Truncate history.txt in installers 2016-11-11 18:23:58 +00:00
zzz
c3181d8561 Transport: Use NTCP for some outbound connections even before
SSU minimums are met (ticket #1835)
2016-11-10 15:09:39 +00:00
zzz
24ecc858f1 Tunnels: Reduce default VTBM records from 5 to 4 2016-11-09 21:32:19 +00:00
zzz
e5bcfe4207 Transport: Add stats for inbound v4/v6 connections (ticket #1854) 2016-11-09 21:08:21 +00:00
zzz
e614b0996d Router: Fix low-memory log messages for non-wrapper (ticket #1795)
Install: Add max memory option to runplain.sh
Build: Fix minimum Java version for Windows
2016-11-08 15:42:22 +00:00
zzz
b559b412aa Crypto: Change serial number in selfsigned certs from int to long
Add CertUtil to command line
2016-11-08 14:09:56 +00:00
zzz
cd775fa38d Transport: Improve IPv6 selection logic
to skip temporary addresses on linux
2016-11-08 03:24:30 +00:00
zzz
ab064fd31e add upnp to command line 2016-11-08 00:15:37 +00:00
zzz
08062aaf64 service cant be android 2016-11-07 14:31:53 +00:00
str4d
e74479317d Add router.jar to Maven Central target 2016-11-07 03:11:32 +00:00
zzz
c9c29520b4 Consistently log authentication failures for all interfaces 2016-11-06 17:20:35 +00:00
zzz
81bbf554e8 sort 2016-11-06 15:31:43 +00:00
zzz
26a24a98ed add java 9 log warning 2016-11-06 15:31:01 +00:00
zzz
e8de1daf65 Util: Consolidate linux service detection code 2016-11-06 00:49:34 +00:00
zzz
11e86110e7 Build: Add support for using libtomcat8-java package, untested 2016-11-05 18:50:22 +00:00
zzz
f42d76b4b4 Console: Add message to ignore InstanceManager warning (ticket #1818) 2016-11-05 17:52:21 +00:00
zzz
e379ca6c54 SusiDNS: Fix jsp EL syntax error with EL 3.0 (Tomcat 8) (ticket #1870) 2016-11-05 15:31:07 +00:00
zzz
5d0b35d53a Console: Improve handling and logging of webapps that fail to start 2016-11-04 17:02:15 +00:00
zzz
8c71b883bb Transports: New config options i2np.udp.minpeers and i2np.udp.minv6peers,
for testing (ticket #1876)
2016-11-04 14:20:56 +00:00
zzz
843351956e build fix 2016-11-04 14:02:06 +00:00
zzz
7197d22f2a Transports: New config option i2np.allowLocal,
replaces i2np.udp.allowLocal and i2np.ntcp.allowLocal,
fixes test networks (ticket #1875)
2016-11-04 13:44:24 +00:00
zzz
b77c4c67a1 i2psnark: Add launch-i2psnark.bat (ticket #1871)
author is MXPLRS|Kirill, adapted from launch-i2psnark,
same license
2016-11-04 13:19:02 +00:00
zzz
62bc616ada Crypto: Certificate tweaks for email subjects 2016-11-01 13:27:12 +00:00
zzz
9e8251fb9f spelling take 2 2016-10-30 17:56:41 +00:00
zzz
6ff9483e07 Console: Java 9 fixes for classloader (ticket #1870)
May not be sufficient for plugins
Unlinkify viewmtn links on /jars, site is down
2016-10-29 16:21:02 +00:00
zzz
484a3903ca Build: Fix typo in jcpuid build.sh for Mac (ticket #1865)
Doc updates for Mac copied from that ticket
2016-10-28 17:10:22 +00:00
zzz
916fc96654 opus mime type 2016-10-28 16:15:16 +00:00
zzz
75345f4da1 Utils: Add Addresses methods for getting multiple results from DNS
ticket #1050, work in progress
2016-10-28 16:14:44 +00:00
zzz
e603437500 drop empty wily dir 2016-10-28 16:01:12 +00:00
zzz
d49a778b68 javadoc typo 2016-10-28 16:00:25 +00:00
zzz
95ae86d962 Jrobin: Fix for error in DeallocationHelper on Java version 9-internal 2016-10-28 15:18:08 +00:00
zzz
51e35eb572 Utils: Handle Java version detection for internal or ea versions 2016-10-28 15:08:13 +00:00
zzz
4f0cae59c2 Crypto: Remove deprecated Sha256Standalone as scheduled
This will break Syndie 1.105 and earlier, users must upgrade to 1.107
2016-10-28 01:52:07 +00:00
zzz
886dbf1172 Crypto: Generate more-conforming selfsigned certs (ticket #1853) 2016-10-28 01:39:01 +00:00
zzz
04392069a6 JRobin: Fix for Java 9 to remove dependency on Sun private classes
https://github.com/OpenNMS/jrobin/issues/3
http://stackoverflow.com/questions/1854398/how-to-garbage-collect-a-direct-buffer-java
Code from http://sourceforge.net/p/tuer/code/HEAD/tree/pre_beta/src/main/java/engine/misc/DeallocationHelper.java
unmodified, GPLv2
2016-10-26 19:31:40 +00:00
zzz
78acf707dc JRobin: 1.6.0-1, 2014-10-28, checked in as source
from https://github.com/OpenNMS/jrobin/releases
Replaces 1.5.9.1 from 2008-09-05
Needed for Java 9 to remove dependency on Sun private classes.
No modifications, but includes only core, data, and graph;
cmd, convertor, inspector, and tests are not included.
Using source instead of jar because:
 - Release jar not available
 - Additional change will be needed for Java 9
   to remove dependency on Sun private classes, see:
   https://github.com/OpenNMS/jrobin/issues/3
2016-10-26 17:45:34 +00:00
zzz
08d1ea89bf Build: Set Java 7 build target for all jars;
embedders (esp. Android) targetting 1.6 must
set javac.version=1.6 in override.properties and set
both bootclasspath variables.
2016-10-26 16:56:13 +00:00
zzz
2b6fd49a53 Update GettextResource.java from GNU gettext 0.19.8
Only change is in comment block.
Previous checkin didn't have gettext version, so do this
just so we know what version we are on.
2016-10-26 14:54:59 +00:00
zzz
3063e37cbd Systray: Remove old 32-bit Windows implementation, replaced by DTG 2016-10-25 23:59:20 +00:00
zzz
d2569fa446 i2psnark: Don't count unchoked but uninterested peers as uploaders
when calculating global uploader limit, to allow more upload slots,
especially when some torrents are stalled.
Convert some shared fields to atomics for concurrency.
2016-10-25 22:30:55 +00:00
zzz
8a8452290c Zxing 3.3.0 2016-10-25 15:04:55 +00:00
zzz
d2f7b65282 SSU: Increase max IPv6 MTU (proposal #127) 2016-10-25 13:39:33 +00:00
zzz
80966d60c1 Crypto: Create keystore directory when making SSL keys (ticket #1866)
When we switched to new way of making keys in 0.9.25,
we omitted the mkdir step, which broke it.
2016-10-23 16:38:26 +00:00
zzz
85223303f2 Jetty 8.1.21.v20160908 2016-10-22 16:22:08 +00:00
zzz
0860bd3736 one more gl translation 2016-10-22 15:24:51 +00:00
zzz
b53bf7844b New Chinese (Taiwan) translations for susidns, susimail, debian 2016-10-22 14:19:17 +00:00
zzz
75514ddd87 New Korean translation 2016-10-22 13:51:25 +00:00
zzz
35642e2661 New initial news translations: Czech, Galician, Greek 2016-10-22 13:20:20 +00:00
zzz
c24ddf5deb Build: Fix jbigi build for Arch Linux and others when using Java 8 (ticket #1863) 2016-10-22 12:58:50 +00:00
zzz
f436fd08ed Add MTU to command line utils 2016-10-21 22:23:48 +00:00
zzz
dc523b78d4 CSS fix for more flags 2016-10-21 22:05:54 +00:00
zzz
06a599b4e7 Add Galician language
Flag converted from:
https://en.wikipedia.org/wiki/File:Flag_of_Galicia.svg
Public Domain
2016-10-21 22:00:51 +00:00
zzz
27cd1a6a6e Console: Remove calls to deprecated two-arg setStatus() 2016-10-21 21:38:55 +00:00
zzz
b6521ed884 Wrapper: Update to wrapper 3.5.30
All binaries from Tanuki delta pack,
except for armhf (armv6), compiled on Raspberry Pi:
  ant 1.8.2
  javac 1.6.0_38
  gcc 4.6.3-14+rpi1
Windows binaries remain unchanged as we must recompile them ourselves
(32 bit just to change the icon; 64 bit is not provided by Tanuki)
2016-10-21 21:01:36 +00:00
zzz
71f7c712cd NetDB: Disallow RSA for RI or LS 2016-10-21 18:21:12 +00:00
zzz
f5f411b62f Data: Cache serialized leasesets on floodfills 2016-10-21 18:08:31 +00:00
zzz
d367149048 Tomcat 6.0.47 2016-10-21 17:42:50 +00:00
zzz
1bd5ebd8ec Crypto: Actually use a random nonzero byte in ElGamal,
as our specification says
2016-10-21 17:19:44 +00:00
zzz
534609e83a unused import 2016-10-21 17:13:58 +00:00
zzz
082a5d3c0f move siphash test from util to crypto 2016-10-21 15:21:24 +00:00
zzz
cee3ebbb23 less wtf 2016-10-21 15:20:35 +00:00
zzz
9b27251473 SSU: Fix minimum version check for IPv6 peer test (ticket #1861) 2016-10-20 18:31:32 +00:00
zzz
022479aff9 Build: Don't include jbigi.jar in next release update 2016-10-20 18:23:31 +00:00
zzz
adcee462e3 Build: Add library jars to i2p.jar classpath for Debian builds 2016-10-20 18:20:24 +00:00
zzz
7d070e6caf i2psnark: Add ids to rows, add to per-torrent show peers link 2016-10-20 18:04:56 +00:00
zzz
dcdf3e197c CSS h1 letter spacing tweak 2016-10-20 17:27:24 +00:00
zzz
6b5b3617d4 Debian: Update package descriptions, allow Java 9 2016-10-20 17:23:42 +00:00
zzz
be9f7dbf6e Fix HTML error on /configservice 2016-10-20 17:15:51 +00:00
zzz
38c9cb98a9 Updates for Debian builds 2016-10-18 14:50:06 +00:00
zzz
d8d0414ec4 Updates for launchpad builds 2016-10-17 22:16:35 +00:00
437 changed files with 64684 additions and 36218 deletions

View File

@@ -11,6 +11,7 @@ trans.fr = apps/i2ptunnel/locale/messages_fr.po
trans.hu = apps/i2ptunnel/locale/messages_hu.po
trans.it = apps/i2ptunnel/locale/messages_it.po
trans.ja = apps/i2ptunnel/locale/messages_ja.po
trans.ko = apps/i2ptunnel/locale/messages_ko.po
trans.nb = apps/i2ptunnel/locale/messages_nb.po
trans.nl = apps/i2ptunnel/locale/messages_nl.po
trans.nn = apps/i2ptunnel/locale/messages_nn.po
@@ -21,6 +22,7 @@ trans.ro = apps/i2ptunnel/locale/messages_ro.po
trans.ru_RU = apps/i2ptunnel/locale/messages_ru.po
trans.sk = apps/i2ptunnel/locale/messages_sk.po
trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po
trans.tr_TR = apps/i2ptunnel/locale/messages_tr.po
trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po
trans.vi = apps/i2ptunnel/locale/messages_vi.po
trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
@@ -39,6 +41,7 @@ trans.hu = apps/i2ptunnel/locale-proxy/messages_hu.po
;; Java converts id to in
trans.id = apps/i2ptunnel/locale-proxy/messages_in.po
trans.it = apps/i2ptunnel/locale-proxy/messages_it.po
trans.ko = apps/i2ptunnel/locale-proxy/messages_ko.po
trans.nb = apps/i2ptunnel/locale-proxy/messages_nb.po
trans.nl = apps/i2ptunnel/locale-proxy/messages_nl.po
trans.pl = apps/i2ptunnel/locale-proxy/messages_pl.po
@@ -68,6 +71,7 @@ trans.fr = apps/routerconsole/locale/messages_fr.po
trans.hu = apps/routerconsole/locale/messages_hu.po
trans.it = apps/routerconsole/locale/messages_it.po
trans.ja = apps/routerconsole/locale/messages_ja.po
trans.ko = apps/routerconsole/locale/messages_ko.po
trans.nb = apps/routerconsole/locale/messages_nb.po
trans.nl = apps/routerconsole/locale/messages_nl.po
trans.pl = apps/routerconsole/locale/messages_pl.po
@@ -86,10 +90,13 @@ trans.zh_TW = apps/routerconsole/locale/messages_zh_TW.po
source_file = apps/routerconsole/locale-news/messages_en.po
source_lang = en
trans.ar = apps/routerconsole/locale-news/messages_ar.po
trans.cs = apps/routerconsole/locale-news/messages_cs.po
trans.de = apps/routerconsole/locale-news/messages_de.po
trans.el = apps/routerconsole/locale-news/messages_el.po
trans.es = apps/routerconsole/locale-news/messages_es.po
trans.fi = apps/routerconsole/locale-news/messages_fi.po
trans.fr = apps/routerconsole/locale-news/messages_fr.po
trans.gl = apps/routerconsole/locale-news/messages_gl.po
trans.he = apps/routerconsole/locale-news/messages_he.po
;; Java converts id to in
trans.id = apps/routerconsole/locale-news/messages_in.po
@@ -125,9 +132,11 @@ trans.et_EE = apps/routerconsole/locale-countries/messages_et.po
trans.fa = apps/routerconsole/locale-countries/messages_fa.po
trans.fi = apps/routerconsole/locale-countries/messages_fi.po
trans.fr = apps/routerconsole/locale-countries/messages_fr.po
trans.gl = apps/routerconsole/locale-countries/messages_gl.po
trans.hu = apps/routerconsole/locale-countries/messages_hu.po
trans.it = apps/routerconsole/locale-countries/messages_it.po
trans.ja = apps/routerconsole/locale-countries/messages_ja.po
trans.ko = apps/routerconsole/locale-countries/messages_ko.po
trans.mg = apps/routerconsole/locale-countries/messages_mg.po
trans.nb = apps/routerconsole/locale-countries/messages_nb.po
trans.nl = apps/routerconsole/locale-countries/messages_nl.po
@@ -139,8 +148,8 @@ trans.ru_RU = apps/routerconsole/locale-countries/messages_ru.po
trans.sk = apps/routerconsole/locale-countries/messages_sk.po
trans.sq = apps/routerconsole/locale-countries/messages_sq.po
trans.sv_SE = apps/routerconsole/locale-countries/messages_sv.po
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
trans.tr_TR = apps/routerconsole/locale-countries/messages_tr.po
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
trans.vi = apps/routerconsole/locale-countries/messages_vi.po
trans.zh_CN = apps/routerconsole/locale-countries/messages_zh.po
trans.zh_TW = apps/routerconsole/locale-countries/messages_zh_TW.po
@@ -157,6 +166,7 @@ trans.fr = apps/i2psnark/locale/messages_fr.po
trans.hu = apps/i2psnark/locale/messages_hu.po
trans.it = apps/i2psnark/locale/messages_it.po
trans.ja = apps/i2psnark/locale/messages_ja.po
trans.ko = apps/i2psnark/locale/messages_ko.po
trans.nb = apps/i2psnark/locale/messages_nb.po
trans.nl = apps/i2psnark/locale/messages_nl.po
trans.pl = apps/i2psnark/locale/messages_pl.po
@@ -182,9 +192,11 @@ trans.el = apps/susidns/locale/messages_el.po
trans.es = apps/susidns/locale/messages_es.po
trans.fi = apps/susidns/locale/messages_fi.po
trans.fr = apps/susidns/locale/messages_fr.po
trans.gl = apps/susidns/locale/messages_gl.po
trans.hu = apps/susidns/locale/messages_hu.po
trans.it = apps/susidns/locale/messages_it.po
trans.ja = apps/susidns/locale/messages_ja.po
trans.ko = apps/susidns/locale/messages_ko.po
trans.nl = apps/susidns/locale/messages_nl.po
trans.pl = apps/susidns/locale/messages_pl.po
trans.pt = apps/susidns/locale/messages_pt.po
@@ -196,6 +208,7 @@ trans.tr_TR = apps/susidns/locale/messages_tr.po
trans.uk_UA = apps/susidns/locale/messages_uk.po
trans.vi = apps/susidns/locale/messages_vi.po
trans.zh_CN = apps/susidns/locale/messages_zh.po
trans.zh_TW = apps/susidns/locale/messages_zh_TW.po
[I2P.desktopgui]
source_file = apps/desktopgui/locale/messages_en.po
@@ -211,6 +224,7 @@ trans.es = apps/desktopgui/locale/messages_es.po
trans.fa = apps/desktopgui/locale/messages_fa.po
trans.fi = apps/desktopgui/locale/messages_fi.po
trans.fr = apps/desktopgui/locale/messages_fr.po
trans.gl = apps/desktopgui/locale/messages_gl.po
trans.hu = apps/desktopgui/locale/messages_hu.po
;; Java converts id to in
trans.id = apps/desktopgui/locale/messages_in.po
@@ -242,11 +256,13 @@ trans.de = apps/susimail/locale/messages_de.po
trans.es = apps/susimail/locale/messages_es.po
trans.fi = apps/susimail/locale/messages_fi.po
trans.fr = apps/susimail/locale/messages_fr.po
trans.gl = apps/susimail/locale/messages_gl.po
trans.hu = apps/susimail/locale/messages_hu.po
;; Java converts id to in
trans.id = apps/susimail/locale/messages_in.po
trans.it = apps/susimail/locale/messages_it.po
trans.ja = apps/susimail/locale/messages_ja.po
trans.ko = apps/susimail/locale/messages_ko.po
trans.mg = apps/susimail/locale/messages_mg.po
trans.nl = apps/susimail/locale/messages_nl.po
trans.pl = apps/susimail/locale/messages_pl.po
@@ -260,6 +276,7 @@ trans.tr_TR = apps/susimail/locale/messages_tr.po
trans.uk_UA = apps/susimail/locale/messages_uk.po
trans.vi = apps/susimail/locale/messages_vi.po
trans.zh_CN = apps/susimail/locale/messages_zh.po
trans.zh_TW = apps/susimail/locale/messages_zh_TW.po
[I2P.debconf]
source_file = debian/po/templates.pot
@@ -287,6 +304,7 @@ trans.sv_SE = debian/po/sv.po
trans.tr_TR = debian/po/tr.po
trans.uk_UA = debian/po/uk.po
trans.zh_CN = debian/po/zh.po
trans.zh_TW = debian/po/zh_TW.po
[I2P.i2prouter-script]
source_file = installer/resources/locale/po/messages_en.po
@@ -300,10 +318,8 @@ trans.es = installer/resources/locale/po/messages_es.po
trans.fr = installer/resources/locale/po/messages_fr.po
trans.id = installer/resources/locale/po/messages_id.po
trans.it = installer/resources/locale/po/messages_it.po
trans.pl = installer/resources/locale/po/messages_pl.po
trans.ja = installer/resources/locale/po/messages_ja.po
;; currently fails check
;;trans.ko = installer/resources/locale/po/messages_ko.po
trans.ko = installer/resources/locale/po/messages_ko.po
trans.nl = installer/resources/locale/po/messages_nl.po
trans.pl = installer/resources/locale/po/messages_pl.po
trans.pt = installer/resources/locale/po/messages_pt.po
@@ -326,6 +342,8 @@ trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties
trans.fi = core/java/src/gnu/getopt/MessagesBundle_fi.properties
trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties
;; currently corrupt, non-UTF-8
;;trans.gl = core/java/src/gnu/getopt/MessagesBundle_gl.properties
trans.hu = core/java/src/gnu/getopt/MessagesBundle_hu.properties
;; Java converts id to in
trans.id = core/java/src/gnu/getopt/MessagesBundle_in.properties
@@ -358,9 +376,11 @@ trans.de = apps/ministreaming/locale/messages_de.po
trans.es = apps/ministreaming/locale/messages_es.po
trans.fi = apps/ministreaming/locale/messages_fi.po
trans.fr = apps/ministreaming/locale/messages_fr.po
trans.gl = apps/ministreaming/locale/messages_gl.po
;; Java converts id to in
trans.id = apps/ministreaming/locale/messages_in.po
trans.it = apps/ministreaming/locale/messages_it.po
trans.ko = apps/ministreaming/locale/messages_ko.po
trans.nb = apps/ministreaming/locale/messages_nb.po
trans.nl = apps/ministreaming/locale/messages_nl.po
trans.pl = apps/ministreaming/locale/messages_pl.po

View File

@@ -36,7 +36,7 @@ Public domain except as listed below:
Copyright (c) 2003, TheCrypto
See licenses/LICENSE-ElGamalDSA.txt
SHA256 and HMAC:
HMAC:
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
See licenses/LICENSE-SHA256.txt
@@ -64,7 +64,7 @@ Public domain except as listed below:
Copyright 2006 Gregory Rubin grrubin@gmail.com
See licenses/LICENSE-HashCash.txt
GettextResource from gettext v0.18:
GettextResource from gettext v0.19.8:
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
See licenses/LICENSE-LGPLv2.1.txt
@@ -150,8 +150,8 @@ Installer:
Java Service Wrapper Community Edition 32-bit 3.5.25:
Copyright (C) 1999-2011 Tanuki Software, Ltd. All Rights Reserved.
Java Service Wrapper Community Edition 32-bit 3.5.30:
Copyright (C) 1999-2016 Tanuki Software, Ltd. All Rights Reserved.
See licenses/LICENSE-Wrapper.txt
@@ -161,6 +161,8 @@ Jbigi Libraries (jbigi.jar):
GMP 4.3.2 / 5.0.2:
Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
See licenses/LICENSE-LGPLv3.txt
GMP 6.0.0:
See licenses/LICENSE-GPLv2.txt
Applications:
@@ -207,18 +209,23 @@ Applications:
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Copyright (c) 2008 Alexander von Gernler. All rights reserved.
See licenses/LICENSE-BSD.txt
Zxing:
Zxing 3.3.0:
See licenses/LICENSE-Apache2.0.txt
Jetty 8.1.17.v20150415:
Jetty 8.1.21.v20160908:
See licenses/ABOUT-Jetty.html
See licenses/NOTICE-Jetty.html
See licenses/LICENSE-Apache2.0.txt
See licenses/LICENSE-ECLIPSE-1.0.html
See licenses/NOTICE-Commons-Logging.txt
JRobin 1.5.9.1:
JRobin 1.6.0-1:
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
Copyright (c) 2011 The OpenNMS Group, Inc.
See licenses/LICENSE-LGPLv2.1.txt
DeallocationHelper:
Copyright (c) 2006-2016 Julien Gouesse
See licenses/LICENSE-GPLv2.txt
Ministreaming Lib:
By mihi.
@@ -276,8 +283,8 @@ Applications:
Bundles systray4j-2.4.1:
See licenses/LICENSE-LGPLv2.1.txt
Tomcat 6.0.44:
Copyright 1999-2015 The Apache Software Foundation
Tomcat 6.0.48:
Copyright 1999-2016 The Apache Software Foundation
See licenses/LICENSE-Apache2.0.txt
See licenses/NOTICE-Tomcat.txt

View File

@@ -48,8 +48,9 @@ javac.classpath=\
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.source=1.5
javac.target=1.5
javac.version=1.7
javac.source=${javac.version}
javac.target=${javac.version}
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\

View File

@@ -165,7 +165,7 @@ public class BOB implements Runnable, ClientApp {
if (classResource != null) {
String classPath = classResource.toString();
if (classPath.startsWith("jar")) {
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
String manifestPath = classPath.substring(0, classPath.lastIndexOf('!') + 1) +
"/META-INF/MANIFEST.MF";
try {
Manifest manifest = new Manifest(new URL(manifestPath).openStream());

View File

@@ -7,7 +7,7 @@
<property name="jar" value="addressbook.jar"/>
<property name="war" value="addressbook.war"/>
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<target name="init">
<mkdir dir="${build}"/>
@@ -86,6 +86,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -106,6 +108,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
<delete dir="${dist}/tmp"/>

View File

@@ -76,7 +76,7 @@ class HostTxtParser {
public static HostTxtEntry parse(String inputLine, boolean allowCommandOnly) {
if (inputLine.startsWith(";"))
return null;
int comment = inputLine.indexOf("#");
int comment = inputLine.indexOf('#');
String kv;
String sprops;
if (comment >= 0) {

View File

@@ -7,7 +7,7 @@
<property name="jar" value="desktopgui.jar"/>
<property name="javadoc" value="javadoc"/>
<property name="javac.compilerargs" value=""/>
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<property name="require.gettext" value="true" />
<condition property="no.bundle">
@@ -83,6 +83,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -0,0 +1,94 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the desktopgui package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# Uberius Crypto <uberius@anonymail.tech>, 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2016-10-22 05:24+0000\n"
"Last-Translator: Uberius Crypto <uberius@anonymail.tech>\n"
"Language-Team: Galician (http://www.transifex.com/otf/I2P/language/gl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr "Iniciar I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "I2P is starting!"
msgstr "I2P está a se iniciar!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "Starting"
msgstr "Iniciando"
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lanzar Navegador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar a Bandexa do Sistema I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Inhabilitar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Reiniciar I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Deter I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Reiniciar I2P Inmediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Deter I2P Inmediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar Apagado I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Apagar en {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Apagar de contado"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Rede"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Clic co botón dereito para acceder ó menú"

View File

@@ -26,7 +26,7 @@
</target>
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<property name="require.gettext" value="true" />
<condition property="no.bundle">
@@ -84,6 +84,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -130,6 +132,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>
@@ -287,6 +291,7 @@
<delete dir="./dist" />
<mkdir dir="./dist" />
<copy file="../launch-i2psnark" todir="./dist/" />
<copy file="../launch-i2psnark.bat" todir="./dist/" />
<mkdir dir="./dist/contexts" />
<copy file="../standalone-context.xml" tofile="./dist/contexts/context.xml" />
<mkdir dir="./dist/docroot" />

View File

@@ -65,6 +65,7 @@ class PeerCheckerTask implements Runnable
Peer worstDownloader = null;
int uploaders = 0;
int interestedUploaders = 0;
int removedCount = 0;
long uploaded = 0;
@@ -76,7 +77,9 @@ class PeerCheckerTask implements Runnable
int uploadLimit = coordinator.allowedUploaders();
boolean overBWLimit = coordinator.overUpBWLimit();
if (_log.shouldLog(Log.DEBUG))
_log.debug("peers: " + peerList.size() + " limit: " + uploadLimit + " overBW? " + overBWLimit);
_log.debug("START peers: " + peerList.size() + " uploaders: " + coordinator.getUploaders() +
" interested: " + coordinator.getInterestedUploaders() +
" limit: " + uploadLimit + " overBW? " + overBWLimit);
DHT dht = _util.getDHT();
for (Peer peer : peerList) {
@@ -98,7 +101,9 @@ class PeerCheckerTask implements Runnable
continue;
}
if (!peer.isChoking())
// we only count choking AND interested, so as not to steal a slot
// from some other torrent
if (peer.isInterested() && !peer.isChoking())
uploaders++;
long upload = peer.getUploaded();
@@ -128,20 +133,23 @@ class PeerCheckerTask implements Runnable
// If we are at our max uploaders and we have lots of other
// interested peers try to make some room.
// (Note use of coordinator.uploaders)
if (((coordinator.uploaders == uploadLimit
&& coordinator.interestedAndChoking > 0)
|| coordinator.uploaders > uploadLimit
|| overBWLimitChoke)
int cup = coordinator.getUploaders();
if (((cup == uploadLimit
&& coordinator.getInterestedAndChoking() > 0)
|| cup > uploadLimit
|| overBWLimitChoke)
&& !peer.isChoking())
{
// Check if it still wants pieces from us.
if (!peer.isInterested())
{
// Note that we only choke if we are over our limits,
// so a peer may remain unchoked even if uninterested.
if (_log.shouldLog(Log.DEBUG))
_log.debug("Choke uninterested peer: " + peer);
peer.setChoking(true);
uploaders--;
coordinator.uploaders--;
coordinator.decrementUploaders(false);
// Put it at the back of the list
removed.add(peer);
@@ -152,7 +160,8 @@ class PeerCheckerTask implements Runnable
_log.debug("BW limit (" + upload + "/" + uploaded + "), choke peer: " + peer);
peer.setChoking(true);
uploaders--;
coordinator.uploaders--;
interestedUploaders--;
coordinator.decrementUploaders(true);
removedCount++;
// Put it at the back of the list for fairness, even though we won't be unchoking this time
@@ -165,7 +174,8 @@ class PeerCheckerTask implements Runnable
_log.debug("Choke choking peer: " + peer);
peer.setChoking(true);
uploaders--;
coordinator.uploaders--;
interestedUploaders--;
coordinator.decrementUploaders(true);
removedCount++;
// Put it at the back of the list
@@ -178,7 +188,8 @@ class PeerCheckerTask implements Runnable
_log.debug("Choke uninteresting peer: " + peer);
peer.setChoking(true);
uploaders--;
coordinator.uploaders--;
interestedUploaders--;
coordinator.decrementUploaders(true);
removedCount++;
// Put it at the back of the list
@@ -193,7 +204,8 @@ class PeerCheckerTask implements Runnable
_log.debug("Choke downloader that doesn't deliver: " + peer);
peer.setChoking(true);
uploaders--;
coordinator.uploaders--;
interestedUploaders--;
coordinator.decrementUploaders(true);
removedCount++;
// Put it at the back of the list
@@ -230,11 +242,11 @@ class PeerCheckerTask implements Runnable
// Resync actual uploaders value
// (can shift a bit by disconnecting peers)
coordinator.uploaders = uploaders;
coordinator.setUploaders(uploaders, interestedUploaders);
// Remove the worst downloader if needed. (uploader if seeding)
if (((uploaders == uploadLimit
&& coordinator.interestedAndChoking > 0)
&& coordinator.getInterestedAndChoking() > 0)
|| uploaders > uploadLimit)
&& worstDownloader != null)
{
@@ -242,28 +254,34 @@ class PeerCheckerTask implements Runnable
_log.debug("Choke worst downloader: " + worstDownloader);
worstDownloader.setChoking(true);
coordinator.uploaders--;
coordinator.decrementUploaders(worstDownloader.isInterested());
removedCount++;
// Put it at the back of the list
removed.add(worstDownloader);
}
// Optimistically unchoke a peer
if ((!overBWLimit) && !coordinator.overUpBWLimit(uploaded))
coordinator.unchokePeer();
// Put peers back at the end of the list that we removed earlier.
boolean coordOver = coordinator.overUpBWLimit(uploaded);
synchronized (coordinator.peers) {
if ((!overBWLimit) && !coordOver) {
// Optimistically unchoke a peer
// must be called inside synch
coordinator.unchokePeer();
}
// Put peers back at the end of the list that we removed earlier.
for(Peer peer : removed) {
if (coordinator.peers.remove(peer))
coordinator.peers.add(peer);
}
}
coordinator.interestedAndChoking += removedCount;
coordinator.addInterestedAndChoking(removedCount);
// store the rates
coordinator.setRateHistory(uploaded, downloaded);
if (_log.shouldLog(Log.DEBUG))
_log.debug("END peers: " + peerList.size() + " uploaders: " + uploaders +
" interested: " + interestedUploaders);
// close out unused files, but we don't need to do it every time
Storage storage = coordinator.getStorage();

View File

@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import net.i2p.I2PAppContext;
@@ -74,16 +75,23 @@ class PeerCoordinator implements PeerListener
public static final long MAX_INACTIVE = 8*60*1000;
/**
* Approximation of the number of current uploaders.
* Approximation of the number of current uploaders (unchoked peers),
* whether interested or not.
* Resynced by PeerChecker once in a while.
* External use by PeerCheckerTask only.
*/
int uploaders;
private final AtomicInteger uploaders = new AtomicInteger();
/**
* Approximation of the number of current uploaders (unchoked peers),
* that are interested.
* Resynced by PeerChecker once in a while.
*/
private final AtomicInteger interestedUploaders = new AtomicInteger();
/**
* External use by PeerCheckerTask only.
*/
int interestedAndChoking;
private final AtomicInteger interestedAndChoking = new AtomicInteger();
// final static int MAX_DOWNLOADERS = MAX_CONNECTIONS;
// int downloaders = 0;
@@ -627,8 +635,9 @@ class PeerCoordinator implements PeerListener
return false;
}
// (Optimistically) unchoke. Should be called with peers synchronized
/**
* (Optimistically) unchoke. Must be called with peers synchronized
*/
void unchokePeer()
{
// linked list will contain all interested peers that we choke.
@@ -645,7 +654,7 @@ class PeerCoordinator implements PeerListener
if (peer.isChoking() && peer.isInterested())
{
count++;
if (uploaders < maxUploaders)
if (uploaders.get() < maxUploaders)
{
if (peer.isInteresting() && !peer.isChoked())
interested.add(unchokedCount++, peer);
@@ -655,20 +664,22 @@ class PeerCoordinator implements PeerListener
}
}
while (uploaders < maxUploaders && !interested.isEmpty())
int up = uploaders.get();
while (up < maxUploaders && !interested.isEmpty())
{
Peer peer = interested.remove(0);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unchoke: " + peer);
peer.setChoking(false);
uploaders++;
up = uploaders.incrementAndGet();
interestedUploaders.incrementAndGet();
count--;
// Put peer back at the end of the list.
peers.remove(peer);
peers.add(peer);
peerCount = peers.size();
}
interestedAndChoking = count;
interestedAndChoking.set(count);
}
/**
@@ -1098,11 +1109,12 @@ class PeerCoordinator implements PeerListener
{
if (interest)
{
if (uploaders < allowedUploaders())
if (uploaders.get() < allowedUploaders())
{
if(peer.isChoking())
{
uploaders++;
uploaders.incrementAndGet();
interestedUploaders.incrementAndGet();
peer.setChoking(false);
if (_log.shouldLog(Log.INFO))
_log.info("Unchoke: " + peer);
@@ -1487,22 +1499,102 @@ class PeerCoordinator implements PeerListener
*/
public int allowedUploaders()
{
if (listener != null && listener.overUploadLimit(uploaders)) {
int up = uploaders.get();
if (listener != null && listener.overUploadLimit(interestedUploaders.get())) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Over limit, uploaders was: " + uploaders);
return uploaders - 1;
} else if (uploaders < MAX_UPLOADERS)
return uploaders + 1;
else
_log.debug("Over limit, uploaders was: " + up);
return up - 1;
} else if (up < MAX_UPLOADERS) {
return up + 1;
} else {
return MAX_UPLOADERS;
}
}
/**
* Uploaders whether interested or not
* Use this for per-torrent limits.
*
* @return current
* @since 0.8.4
*/
public int getUploaders() {
return uploaders;
int rv = uploaders.get();
if (rv > 0) {
int max = getPeers();
if (rv > max)
rv = max;
}
return rv;
}
/**
* Uploaders, interested only.
* Use this to calculate the global total, so that
* unchoked but uninterested peers don't count against the global limit.
*
* @return current
* @since 0.9.28
*/
public int getInterestedUploaders() {
int rv = interestedUploaders.get();
if (rv > 0) {
int max = getPeers();
if (rv > max)
rv = max;
}
return rv;
}
/**
* Set the uploaders and interestedUploaders counts
*
* @since 0.9.28
* @param upl whether interested or not
* @param inter interested only
*/
public void setUploaders(int upl, int inter) {
if (upl < 0)
upl = 0;
else if (upl > MAX_UPLOADERS)
upl = MAX_UPLOADERS;
uploaders.set(upl);
if (inter < 0)
inter = 0;
else if (inter > MAX_UPLOADERS)
inter = MAX_UPLOADERS;
interestedUploaders.set(inter);
}
/**
* Decrement the uploaders and (if set) the interestedUploaders counts
*
* @since 0.9.28
*/
public void decrementUploaders(boolean isInterested) {
int up = uploaders.decrementAndGet();
if (up < 0)
uploaders.set(0);
if (isInterested) {
up = interestedUploaders.decrementAndGet();
if (up < 0)
interestedUploaders.set(0);
}
}
/**
* @return current
* @since 0.9.28
*/
public int getInterestedAndChoking() {
return interestedAndChoking.get();
}
/**
* @since 0.9.28
*/
public void addInterestedAndChoking(int toAdd) {
interestedAndChoking.addAndGet(toAdd);
}
public boolean overUpBWLimit()

View File

@@ -1337,7 +1337,7 @@ public class Snark
int totalUploaders = 0;
for (PeerCoordinator c : _peerCoordinatorSet) {
if (!c.halted())
totalUploaders += c.uploaders;
totalUploaders += c.getInterestedUploaders();
}
int limit = _util.getMaxUploaders();
if (_log.shouldLog(Log.DEBUG))

View File

@@ -958,7 +958,7 @@ public class TrackerClient implements Runnable {
{
announce = a;
String s = a.substring(7);
host = s.substring(0, s.indexOf("/"));
host = s.substring(0, s.indexOf('/'));
isPrimary = p;
interval = INITIAL_SLEEP;
}

View File

@@ -123,6 +123,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
private final AtomicLong _rxBytes = new AtomicLong();
private final AtomicLong _txBytes = new AtomicLong();
private long _started;
private long _nodesLastSaved;
/** all-zero NID used for pings */
public static final NID FAKE_NID = new NID(new byte[NID.HASH_LENGTH]);
@@ -156,6 +157,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
private static final long CLEAN_TIME = 63*1000;
private static final long EXPLORE_TIME = 877*1000;
private static final long BLACKLIST_CLEAN_TIME = 17*60*1000;
private static final long NODES_SAVE_TIME = 3*60*60*1000;
public static final String DHT_FILE_SUFFIX = ".dht.dat";
private static final int SEND_CRYPTO_TAGS = 8;
@@ -635,6 +637,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
_txBytes.set(0);
_rxBytes.set(0);
_started = _context.clock().now();
_nodesLastSaved = _started;
}
/**
@@ -866,7 +869,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
@SuppressWarnings("unchecked")
private ReplyWaiter sendQuery(NodeInfo nInfo, Map<String, Object> map, boolean repliable) {
if (nInfo.equals(_myNodeInfo))
throw new IllegalArgumentException("wtf don't send to ourselves");
throw new IllegalArgumentException("don't send to ourselves");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Sending query to: " + nInfo);
if (nInfo.getDestination() == null) {
@@ -916,7 +919,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
@SuppressWarnings("unchecked")
private boolean sendResponse(NodeInfo nInfo, MsgID msgID, Map<String, Object> map) {
if (nInfo.equals(_myNodeInfo))
throw new IllegalArgumentException("wtf don't send to ourselves");
throw new IllegalArgumentException("don't send to ourselves");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Sending response to: " + nInfo);
if (nInfo.getDestination() == null) {
@@ -946,7 +949,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
*/
private boolean sendError(NodeInfo nInfo, MsgID msgID, Map<String, Object> map) {
if (nInfo.equals(_myNodeInfo))
throw new IllegalArgumentException("wtf don't send to ourselves");
throw new IllegalArgumentException("don't send to ourselves");
if (_log.shouldLog(Log.INFO))
_log.info("Sending error to: " + nInfo);
if (nInfo.getDestination() == null) {
@@ -1004,7 +1007,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
return false;
}
if (dest.calculateHash().equals(_myNodeInfo.getHash()))
throw new IllegalArgumentException("wtf don't send to ourselves");
throw new IllegalArgumentException("don't send to ourselves");
byte[] payload = BEncoder.bencode(map);
if (_log.shouldLog(Log.DEBUG)) {
ByteArrayInputStream bais = new ByteArrayInputStream(payload);
@@ -1020,7 +1023,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
payload = dgMaker.makeI2PDatagram(payload);
if (payload == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("WTF DGM fail");
_log.warn("DGM fail");
return false;
}
}
@@ -1040,7 +1043,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
_txBytes.addAndGet(payload.length);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("WTF sendMessage fail");
_log.warn("sendMessage fail");
}
return success;
} catch (I2PSessionException ise) {
@@ -1675,6 +1678,10 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
if (nid.lastSeen() < expire)
iter.remove();
}
if (now - _nodesLastSaved > NODES_SAVE_TIME) {
PersistDHT.saveDHT(_knownNodes, false, _dhtFile);
_nodesLastSaved = now;
}
// TODO sent queries?
if (_log.shouldLog(Log.DEBUG))
_log.debug("KRPC cleaner done, now with " +

View File

@@ -39,9 +39,11 @@ public class ConfigUIHelper {
{ "es", "es", "Spanish", null },
{ "fi", "fi", "Finnish", null },
{ "fr", "fr", "French", null },
//{ "gl", "lang_gl", "Galician", null },
{ "hu", "hu", "Hungarian", null },
{ "it", "it", "Italian", null },
{ "ja", "jp", "Japanese", null },
{ "ko", "kr", "Korean", null },
//{ "mg", "mg", "Malagasy", null },
{ "nl", "nl", "Dutch", null },
{ "nb", "no", "Norwegian Bokmaal", null },

View File

@@ -24,6 +24,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.i2p.CoreVersion;
import net.i2p.data.Base32;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
@@ -1465,7 +1466,7 @@ public class I2PSnarkServlet extends BasicServlet {
String fullBasename = basename;
if (basename.length() > MAX_DISPLAYED_FILENAME_LENGTH) {
String start = basename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH);
if (start.indexOf(" ") < 0 && start.indexOf("-") < 0) {
if (start.indexOf(' ') < 0 && start.indexOf('-') < 0) {
// browser has nowhere to break it
basename = start + HELLIP;
}
@@ -1485,6 +1486,8 @@ public class I2PSnarkServlet extends BasicServlet {
remainingSeconds = -1;
MetaInfo meta = snark.getMetaInfo();
String b64 = Base64.encode(snark.getInfoHash());
String b64Short = b64.substring(0, 6);
// isValid means isNotMagnet
boolean isValid = meta != null;
boolean isMultiFile = isValid && meta.getFiles() != null;
@@ -1542,57 +1545,59 @@ public class I2PSnarkServlet extends BasicServlet {
img = "complete";
txt = _t("Complete");
}
if (curPeers > 0 && !showPeers)
if (curPeers > 0 && !showPeers) {
statusString = toThemeImg(img, "", txt) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + txt +
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else
} else {
statusString = toThemeImg(img, "", txt) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + txt +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
}
} else {
statusString = toThemeImg("complete", "", _t("Complete")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("Complete");
}
} else {
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers) {
statusString = toThemeImg("downloading", "", _t("OK")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("OK") +
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0 && downBps > 0)
} else if (isRunning && curPeers > 0 && downBps > 0) {
statusString = toThemeImg("downloading", "", _t("OK")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("OK") +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning && curPeers > 0 && !showPeers)
} else if (isRunning && curPeers > 0 && !showPeers) {
statusString = toThemeImg("stalled", "", _t("Stalled")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("Stalled") +
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0)
} else if (isRunning && curPeers > 0) {
statusString = toThemeImg("stalled", "", _t("Stalled")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("Stalled") +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning && knownPeers > 0)
} else if (isRunning && knownPeers > 0) {
statusString = toThemeImg("nopeers", "", _t("No Peers")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("No Peers") +
": 0" + thinsp(noThinsp) + knownPeers ;
else if (isRunning)
} else if (isRunning) {
statusString = toThemeImg("nopeers", "", _t("No Peers")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("No Peers");
else
} else {
statusString = toThemeImg("stopped", "", _t("Stopped")) + "</td>" +
"<td class=\"snarkTorrentStatus\">" + _t("Stopped");
}
}
out.write("<tr class=\"" + rowClass + "\">");
out.write("<tr class=\"" + rowClass + "\" id=\"" + b64Short + "\">");
out.write("<td class=\"center\">");
out.write(statusString + "</td>\n\t");
@@ -1697,7 +1702,6 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(formatSize(upBps) + "ps");
out.write("</td>\n\t");
out.write("<td align=\"center\" class=\"snarkTorrentAction\">");
String b64 = Base64.encode(snark.getInfoHash());
if (snark.isChecking()) {
// show no buttons
} else if (isRunning) {
@@ -2596,7 +2600,7 @@ public class I2PSnarkServlet extends BasicServlet {
private static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
private static final String HEADER_A = "<link href=\"";
private static final String HEADER_B = "snark.css\" rel=\"stylesheet\" type=\"text/css\" >";
private static final String HEADER_B = "snark.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";
private static final String TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" >\n" +
@@ -3082,7 +3086,7 @@ public class I2PSnarkServlet extends BasicServlet {
: tx + ": " + directory);
if (showSort)
buf.append("</a>");
int dirSlash = directory.indexOf("/");
int dirSlash = directory.indexOf('/');
if (dirSlash > 0) {
buf.append("&nbsp;");
buf.append(DataHelper.escapeHTML(directory.substring(dirSlash + 1)));

View File

@@ -96,7 +96,7 @@ public class InclusiveByteRange
long first = -1;
long last = -1;
int d = t.indexOf('-');
if (d < 0 || t.indexOf("-",d + 1) >= 0)
if (d < 0 || t.indexOf('-',d + 1) >= 0)
{
if ("bytes".equals(t))
continue;

View File

@@ -105,7 +105,7 @@ class MimeTypes
int i=-1;
while(type==null)
{
i=filename.indexOf(".",i+1);
i=filename.indexOf('.',i+1);
if (i<0 || i>=filename.length())
break;

View File

@@ -0,0 +1,8 @@
@echo off
REM This launches i2psnark and jetty in a separate JVM.
REM The file jetty-i2psnark.xml must be present in the current directory.
REM i2psnark will be accessed at http://127.0.0.1:8002/
set I2P="."
java -jar "%I2P%/i2psnark.jar"

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,7 @@ odt = application/vnd.oasis.opendocument.text
ogm = video/ogg
ogv = video/ogg
oga = audio/ogg
opus = audio/ogg
otc = application/vnd.oasis.opendocument.chart-template
otf = application/vnd.oasis.opendocument.formula-template
otg = application/vnd.oasis.opendocument.graphics-template

View File

@@ -28,7 +28,7 @@
<!-- only used if not set by a higher build.xml -->
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<property name="require.gettext" value="true" />
<target name="compile" depends="depend">
@@ -72,6 +72,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/ui/*.class **/EditBean.class **/IndexBean.class" />
@@ -103,6 +105,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -241,6 +245,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -380,8 +380,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
}
public void runCommand(String cmd, Logging l) {
if (cmd.indexOf(" ") == -1) cmd += " ";
int iii = cmd.indexOf(" ");
if (cmd.indexOf(' ') == -1) cmd += ' ';
int iii = cmd.indexOf(' ');
String cmdname = cmd.substring(0, iii).toLowerCase(Locale.US);
String allargs = cmd.substring(iii + 1);
String[] args = split(allargs, " "); // .split(" "); // java 1.4

View File

@@ -166,14 +166,14 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
_log.debug(getPrefix(requestId) + "Line=[" + line + "]");
if (method == null) { // first line CONNECT blah.i2p:80 HTTP/1.1
int pos = line.indexOf(" ");
int pos = line.indexOf(' ');
if (pos == -1) break; // empty first line
method = line.substring(0, pos);
String request = line.substring(pos + 1);
pos = request.indexOf(":");
pos = request.indexOf(':');
if (pos == -1)
pos = request.indexOf(" ");
pos = request.indexOf(' ');
if (pos == -1) {
host = request;
restofline = "";
@@ -185,7 +185,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
if (host.toLowerCase(Locale.US).endsWith(".i2p")) {
// Destination gets the host name
destination = host;
} else if (host.indexOf(".") != -1) {
} else if (host.indexOf('.') != -1) {
// The request must be forwarded to a outproxy
currentProxy = selectProxy();
if (currentProxy == null) {

View File

@@ -1414,7 +1414,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
}
public static final String DEFAULT_JUMP_SERVERS =
"http://i2host.i2p/cgi-bin/i2hostjump?," +
//"http://i2host.i2p/cgi-bin/i2hostjump?," +
"http://stats.i2p/cgi-bin/jump.cgi?a=," +
"http://no.i2p/jump/," +
"http://i2pjump.i2p/jump/";

View File

@@ -304,7 +304,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
return AuthResult.AUTH_GOOD;
}
}
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
} catch (UnsupportedEncodingException uee) {
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
} catch (ArrayIndexOutOfBoundsException aioobe) {
@@ -363,7 +363,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
PROP_PROXY_DIGEST_SUFFIX);
if (ha1 == null) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
return AuthResult.AUTH_BAD;
}
// get H(A2)
@@ -373,7 +373,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
String hkd = PasswordManager.md5Hex(kd);
if (!response.equals(hkd)) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
if (_log.shouldLog(Log.INFO))
_log.info("Bad digest auth: " + DataHelper.toString(args));
return AuthResult.AUTH_BAD;

View File

@@ -430,7 +430,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
try {
int myPort = Integer.parseInt(key);
String host = (String) e.getValue();
int colon = host.indexOf(":");
int colon = host.indexOf(':');
int port = Integer.parseInt(host.substring(colon + 1));
host = host.substring(0, colon);
InetSocketAddress isa = new InetSocketAddress(host, port);

View File

@@ -167,8 +167,8 @@ public class I2Ping extends I2PTunnelClientBase {
if (line.startsWith("#")) continue; // comments
if (line.startsWith(";")) continue;
if (line.startsWith("!")) continue;
if (line.indexOf("=") != -1) { // maybe file is hosts.txt?
line = line.substring(0, line.indexOf("="));
if (line.indexOf('=') != -1) { // maybe file is hosts.txt?
line = line.substring(0, line.indexOf('='));
}
PingHandler ph = new PingHandler(line, count, localPort, remotePort,
timeout, countPing, reportTimes);

View File

@@ -64,7 +64,7 @@ abstract class IRCFilter {
idx++;
command = field[idx++].toUpperCase(Locale.US);
} catch (IndexOutOfBoundsException ioobe) {
// wtf, server sent borked command?
// server sent borked command?
//_log.warn("Dropping defective message: index out of bounds while extracting command.");
return null;
}
@@ -282,7 +282,7 @@ abstract class IRCFilter {
if(field[0].charAt(0)==':')
return null; // wtf
return null; // ???
String command = field[0].toUpperCase(Locale.US);
@@ -380,7 +380,7 @@ abstract class IRCFilter {
if("USER".equals(command)) {
if (field.length < 3)
return s; // invalid, allow server response
int idx = field[2].lastIndexOf(":");
int idx = field[2].lastIndexOf(':');
if(idx<0)
return "USER user hostname localhost :realname";
String realname = field[2].substring(idx+1);

View File

@@ -131,26 +131,32 @@ class SOCKS5Server extends SOCKSServer {
*/
private void verifyPassword(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException {
int c = in.readUnsignedByte();
if (c != AUTH_VERSION)
if (c != AUTH_VERSION) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Unsupported authentication version");
}
c = in.readUnsignedByte();
if (c <= 0)
if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Bad authentication");
}
byte[] user = new byte[c];
String u = new String(user, "UTF-8");
in.readFully(user);
c = in.readUnsignedByte();
if (c <= 0)
if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
throw new SOCKSException("Bad authentication");
}
byte[] pw = new byte[c];
in.readFully(pw);
// Hopefully these are in UTF-8, since that's what our config file is in
// these throw UnsupportedEncodingException which is an IOE
String u = new String(user, "UTF-8");
String p = new String(pw, "UTF-8");
String configUser = props.getProperty(I2PTunnelHTTPClientBase.PROP_USER);
String configPW = props.getProperty(I2PTunnelHTTPClientBase.PROP_PW);
if ((!u.equals(configUser)) || (!p.equals(configPW))) {
_log.error("SOCKS authorization failure");
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
sendAuthReply(AUTH_FAILURE, out);
throw new SOCKSException("SOCKS authorization failure");
}
@@ -168,7 +174,7 @@ class SOCKS5Server extends SOCKSServer {
private int manageRequest(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException {
int socksVer = in.readUnsignedByte();
if (socksVer != SOCKS_VERSION_5) {
_log.debug("error in SOCKS5 request (protocol != 5? wtf?)");
_log.debug("error in SOCKS5 request (protocol != 5?)");
throw new SOCKSException("Invalid protocol version in request: " + socksVer);
}
@@ -221,7 +227,7 @@ class SOCKS5Server extends SOCKSServer {
{
int addrLen = in.readUnsignedByte();
if (addrLen == 0) {
_log.debug("0-sized address length? wtf?");
_log.debug("0-sized address length?");
throw new SOCKSException("Illegal DOMAINNAME length");
}
byte addr[] = new byte[addrLen];
@@ -315,7 +321,7 @@ class SOCKS5Server extends SOCKSServer {
dreps.writeBytes(domainName);
break;
default:
_log.error("unknown address type passed to sendReply() (" + Integer.toHexString(addressType) + ")! wtf?");
_log.error("unknown address type passed to sendReply() (" + Integer.toHexString(addressType) + ")!");
return;
}
@@ -591,9 +597,13 @@ class SOCKS5Server extends SOCKSServer {
// todo pass the response through?
} catch (IOException e) {
try { destSock.close(); } catch (IOException ioe) {}
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
throw e;
} catch (SOCKSException e) {
try { destSock.close(); } catch (IOException ioe) {}
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
throw e;
}
// that's it, caller will send confirmation to our client
@@ -601,9 +611,10 @@ class SOCKS5Server extends SOCKSServer {
}
// This isn't really the right place for this, we can't stop the tunnel once it starts.
static SOCKSUDPTunnel _tunnel;
static final Object _startLock = new Object();
static byte[] dummyIP = new byte[4];
private static SOCKSUDPTunnel _tunnel;
private static final Object _startLock = new Object();
private static final byte[] dummyIP = new byte[4];
/**
* We got a UDP associate command.
* Loop here looking for more, never return normally,

View File

@@ -23,8 +23,8 @@
<% if (editBean.allowCSS()) {
%><link rel="icon" href="<%=editBean.getTheme()%>images/favicon.ico" />
<link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>default.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<% }
%>
<style type='text/css'>
@@ -284,10 +284,10 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
</label>
<select id="tunnelVariance" name="tunnelVariance" title="Level of Randomization for Tunnel Length" class="selectbox">
<% int tunnelVariance = editBean.getTunnelVariance(curTunnel, 0);
%><option value="0"<%=(tunnelVariance == 0 ? " selected=\"selected\"" : "") %>><%=intl._t("0 hop variance (no ransomization, consistent performance)")%></option>
<option value="1"<%=(tunnelVariance == 1 ? " selected=\"selected\"" : "") %>><%=intl._t("+ 0-1 hop variance (medium additive ransomization, subtractive performance)")%></option>
<option value="2"<%=(tunnelVariance == 2 ? " selected=\"selected\"" : "") %>><%=intl._t("+ 0-2 hop variance (high additive ransomization, subtractive performance)")%></option>
<option value="-1"<%=(tunnelVariance == -1 ? " selected=\"selected\"" : "") %>><%=intl._t("+/- 0-1 hop variance (standard ransomization, standard performance)")%></option>
%><option value="0"<%=(tunnelVariance == 0 ? " selected=\"selected\"" : "") %>><%=intl._t("0 hop variance (no randomization, consistent performance)")%></option>
<option value="1"<%=(tunnelVariance == 1 ? " selected=\"selected\"" : "") %>><%=intl._t("+ 0-1 hop variance (medium additive randomization, subtractive performance)")%></option>
<option value="2"<%=(tunnelVariance == 2 ? " selected=\"selected\"" : "") %>><%=intl._t("+ 0-2 hop variance (high additive randomization, subtractive performance)")%></option>
<option value="-1"<%=(tunnelVariance == -1 ? " selected=\"selected\"" : "") %>><%=intl._t("+/- 0-1 hop variance (standard randomization, standard performance)")%></option>
<option value="-2"<%=(tunnelVariance == -2 ? " selected=\"selected\"" : "") %>><%=intl._t("+/- 0-2 hop variance (not recommended)")%></option>
<% if (tunnelVariance > 2 || tunnelVariance < -2) {
%> <option value="<%=tunnelVariance%>" selected="selected"><%= (tunnelVariance > 2 ? "+ " : "+/- ") %>0-<%=tunnelVariance%> <%=intl._t("hop variance")%></option>

View File

@@ -23,8 +23,8 @@
<% if (editBean.allowCSS()) {
%><link rel="icon" href="<%=editBean.getTheme()%>images/favicon.ico" />
<link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>default.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<% }
%>
<style type='text/css'>

View File

@@ -28,8 +28,8 @@
<% if (indexBean.allowCSS()) {
%><link rel="icon" href="<%=indexBean.getTheme()%>images/favicon.ico" />
<link href="<%=indexBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=indexBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<link href="<%=indexBean.getTheme()%>default.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<link href="<%=indexBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<% }
%>
</head>

View File

@@ -29,8 +29,8 @@
<% if (editBean.allowCSS()) {
%><link rel="icon" href="<%=editBean.getTheme()%>images/favicon.ico" />
<link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>default.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<% }
%>
<style type='text/css'>

View File

@@ -62,8 +62,8 @@
<% if (editBean.allowCSS()) {
%><link rel="icon" href="<%=editBean.getTheme()%>images/favicon.ico" />
<link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>default.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" />
<% }
%>
</head>

View File

@@ -0,0 +1,539 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2ptunnel package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# SEPT____ <xpressengine3@mail.beo.kr>, 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-25 12:28+0000\n"
"PO-Revision-Date: 2016-08-26 05:08+0000\n"
"Last-Translator: SEPT____ <xpressengine3@mail.beo.kr>\n"
"Language-Team: Korean (http://www.transifex.com/otf/I2P/language/ko/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../java/build/Proxy.java:5 ../java/build/Proxy.java:11
#: ../java/build/Proxy.java:40 ../java/build/Proxy.java:46
#: ../java/build/Proxy.java:82 ../java/build/Proxy.java:88
msgid "Website Unreachable"
msgstr "접속할 수 없습니다"
#: ../java/build/Proxy.java:6 ../java/build/Proxy.java:17
#: ../java/build/Proxy.java:29 ../java/build/Proxy.java:41
#: ../java/build/Proxy.java:52 ../java/build/Proxy.java:61
#: ../java/build/Proxy.java:70 ../java/build/Proxy.java:83
#: ../java/build/Proxy.java:92 ../java/build/Proxy.java:103
#: ../java/build/Proxy.java:115 ../java/build/Proxy.java:124
#: ../java/build/Proxy.java:134 ../java/build/Proxy.java:144
#: ../java/build/Proxy.java:156 ../java/build/Proxy.java:169
#: ../java/build/Proxy.java:181 ../java/build/Proxy.java:191
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:209
msgid "Router Console"
msgstr "라우터 콘솔"
#: ../java/build/Proxy.java:7 ../java/build/Proxy.java:18
#: ../java/build/Proxy.java:30 ../java/build/Proxy.java:42
#: ../java/build/Proxy.java:53 ../java/build/Proxy.java:62
#: ../java/build/Proxy.java:71 ../java/build/Proxy.java:84
#: ../java/build/Proxy.java:93 ../java/build/Proxy.java:104
#: ../java/build/Proxy.java:116 ../java/build/Proxy.java:125
#: ../java/build/Proxy.java:135 ../java/build/Proxy.java:145
#: ../java/build/Proxy.java:157 ../java/build/Proxy.java:170
#: ../java/build/Proxy.java:182 ../java/build/Proxy.java:192
msgid "I2P Router Console"
msgstr "I2P 라우터 콘솔"
#: ../java/build/Proxy.java:8 ../java/build/Proxy.java:19
#: ../java/build/Proxy.java:31 ../java/build/Proxy.java:43
#: ../java/build/Proxy.java:54 ../java/build/Proxy.java:63
#: ../java/build/Proxy.java:72 ../java/build/Proxy.java:85
#: ../java/build/Proxy.java:94 ../java/build/Proxy.java:105
#: ../java/build/Proxy.java:117 ../java/build/Proxy.java:126
#: ../java/build/Proxy.java:136 ../java/build/Proxy.java:146
#: ../java/build/Proxy.java:158 ../java/build/Proxy.java:171
#: ../java/build/Proxy.java:183 ../java/build/Proxy.java:193
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:210
msgid "Configuration"
msgstr "설정"
#: ../java/build/Proxy.java:9 ../java/build/Proxy.java:20
#: ../java/build/Proxy.java:32 ../java/build/Proxy.java:44
#: ../java/build/Proxy.java:55 ../java/build/Proxy.java:64
#: ../java/build/Proxy.java:73 ../java/build/Proxy.java:86
#: ../java/build/Proxy.java:95 ../java/build/Proxy.java:106
#: ../java/build/Proxy.java:118 ../java/build/Proxy.java:127
#: ../java/build/Proxy.java:137 ../java/build/Proxy.java:147
#: ../java/build/Proxy.java:159 ../java/build/Proxy.java:172
#: ../java/build/Proxy.java:184 ../java/build/Proxy.java:194
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:210
msgid "Help"
msgstr "도움말"
#: ../java/build/Proxy.java:10 ../java/build/Proxy.java:21
#: ../java/build/Proxy.java:33 ../java/build/Proxy.java:45
#: ../java/build/Proxy.java:56 ../java/build/Proxy.java:65
#: ../java/build/Proxy.java:74 ../java/build/Proxy.java:87
#: ../java/build/Proxy.java:96 ../java/build/Proxy.java:107
#: ../java/build/Proxy.java:119 ../java/build/Proxy.java:128
#: ../java/build/Proxy.java:138 ../java/build/Proxy.java:148
#: ../java/build/Proxy.java:160 ../java/build/Proxy.java:173
#: ../java/build/Proxy.java:185 ../java/build/Proxy.java:195
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:210
msgid "Addressbook"
msgstr "주소록"
#: ../java/build/Proxy.java:12
msgid "The website was not reachable."
msgstr "이 웹사이트에 접속할 수 없습니다"
#: ../java/build/Proxy.java:13
msgid ""
"The website is offline, there is network congestion, or your router is not "
"yet well-integrated with peers."
msgstr "웹사이트가 닫혔거나, 네트워크가 혼잡할 수 있습니다. 혹은 당신의 라우터가 피어들과 충분히 연결되지 않은 상태일 수 있습니다."
#: ../java/build/Proxy.java:14 ../java/build/Proxy.java:49
#: ../java/build/Proxy.java:100 ../java/build/Proxy.java:112
#, java-format
msgid "You may want to {0}retry{1}."
msgstr "{0}재시도{1} 해보시겠습니까?"
#: ../java/build/Proxy.java:15 ../java/build/Proxy.java:27
#: ../java/build/Proxy.java:50 ../java/build/Proxy.java:81
#: ../java/build/Proxy.java:101 ../java/build/Proxy.java:113
#: ../java/build/Proxy.java:154 ../java/build/Proxy.java:179
msgid "Could not find the following destination:"
msgstr "다음의 목적지를 찾을 수 없습니다:"
#: ../java/build/Proxy.java:16 ../java/build/Proxy.java:22
#: ../java/build/Proxy.java:143 ../java/build/Proxy.java:149
msgid "Outproxy Not Found"
msgstr "아웃프록시 발견안됨"
#: ../java/build/Proxy.java:23
msgid ""
"The HTTP outproxy was not reachable, because its lease set was not found."
msgstr "HTTP 아웃프록시와 연결할 수 없습니다. 공유지를 찾을 수 없습니다."
#: ../java/build/Proxy.java:24
msgid ""
"The outproxy is probably down, but there could also be network congestion."
msgstr "아웃프록시가 일시적으로 다운됬을 수 있습니다. 혹은 네트워크가 혼잡한 상태입니다."
#: ../java/build/Proxy.java:25 ../java/build/Proxy.java:152
#: ../java/build/Proxy.java:177 ../java/build/Proxy.java:198
#, java-format
msgid ""
"You may want to {0}retry{1} as this will randomly reselect an outproxy from "
"the pool you have defined {2}here{3} (if you have more than one configured)."
msgstr "아웃프록시 접속은 랜덤이기에, {0}재시도{1} 하여 다른 아웃프록시에 접속할 수 있습니다. from the pool you have defined {2}here{3} (if you have more than one configured)."
#: ../java/build/Proxy.java:26 ../java/build/Proxy.java:153
#: ../java/build/Proxy.java:178 ../java/build/Proxy.java:199
#, java-format
msgid ""
"If you continue to have trouble you may want to edit your outproxy list "
"{0}here{1}."
msgstr "만약 문제가 지속된다면 {0}여기서{1} 아웃프록시 리스트를 변경할 수 있습니다."
#: ../java/build/Proxy.java:28
msgid "Information: New Host Name"
msgstr "정보: 새 호스트 이름"
#: ../java/build/Proxy.java:34
msgid "Information: New Host Name with Address Helper"
msgstr "정보: 새 호스트 이름과 주소록 도우미"
#: ../java/build/Proxy.java:35
msgid ""
"The address helper link you followed is for a new host name that is not in "
"your address book."
msgstr "주소록 도우미는 주소록에 없는 호스트들."
#: ../java/build/Proxy.java:36
msgid "You may save this host name to your local address book."
msgstr "이 호스트 이름을 주소록에 저장하십시오."
#: ../java/build/Proxy.java:37
msgid ""
"If you save it to your address book, you will not see this message again."
msgstr "주소록에 저장한다면, 이 메시지는 다시 보이지 않습니다."
#: ../java/build/Proxy.java:38
msgid ""
"If you do not save it, the host name will be forgotten after the next router"
" restart."
msgstr "저장하지 않는다면, 해당 호스트 이름은 다음 라우터 재시작때 잊혀집니다."
#: ../java/build/Proxy.java:39
msgid ""
"If you do not wish to visit this host, click the \"back\" button on your "
"browser."
msgstr "이 호스트에 접속하지 않으려면, 브라우저의 뒤로가기 버튼을 누르십시오."
#: ../java/build/Proxy.java:47
msgid "The website was not reachable, because its lease set was not found."
msgstr "웹사이트에 접속할 수 없었습니다. 공유지를 찾을 수 없습니다."
#: ../java/build/Proxy.java:48
msgid ""
"The website is probably down, but there could also be network congestion."
msgstr "해당 웹사이트가 다운된 상태인것 같습니다. 혹은 네트워크가 혼잡한 상태입니다."
#: ../java/build/Proxy.java:51 ../java/build/Proxy.java:57
msgid "Warning: Invalid Request URI"
msgstr "경고: 올바르지 않은 URL"
#: ../java/build/Proxy.java:58
msgid "The request URI is invalid, and probably contains illegal characters."
msgstr "URL 주소가 올바르지 않습니다. 혹은 잘못된 특수문자가 포함되어 있을 수 있습니다."
#: ../java/build/Proxy.java:59
msgid ""
"If you clicked a link, check the end of the URI for any characters the "
"browser has mistakenly added on."
msgstr "링크를 클릭하셨다면 주소에 특수문자가 들어가있는지 확인하십시오."
#: ../java/build/Proxy.java:60
msgid "Error: Request Denied"
msgstr "오류: 요청 거부됨"
#: ../java/build/Proxy.java:66
msgid "Error: Local Access"
msgstr "오류: Local Access"
#: ../java/build/Proxy.java:67
msgid "Your browser is misconfigured."
msgstr "브라우저가 잘못 설정되었습니다."
#: ../java/build/Proxy.java:68
msgid ""
"Do not use the proxy to access the router console, localhost, or local LAN "
"destinations."
msgstr "라우터 콘솔, Localhost, 또는 로컬 LAN 목적지에 접속하기 위해 프록시를 사용하지 마십시오."
#: ../java/build/Proxy.java:69
msgid "Website Unknown"
msgstr "Website Unknown"
#: ../java/build/Proxy.java:75
msgid "Website Not Found in Addressbook"
msgstr "웹사이트를 주소록에서 찾을 수 없습니다."
#: ../java/build/Proxy.java:76
msgid "The website was not found in your router's addressbook."
msgstr "라우터 주소록에서 웹사이트를 찾을 수 없습니다."
#: ../java/build/Proxy.java:77
msgid "Check the link or find a Base 32 or Base 64 address."
msgstr "링크를 확인하거나 base32, base64 주소를 찾으십시오."
#: ../java/build/Proxy.java:78
#, java-format
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
msgstr "Base 64 주소가 있으시다면, {0}주소록에 저장하세요{1}."
#: ../java/build/Proxy.java:79
msgid ""
"Otherwise, find a Base 32 or address helper link, or use a jump service link"
" below."
msgstr "또는 주소록 도우미로부터 Base 32 주소를 찾거나 아래의 점프 서비스 링크를 이용하세요."
#: ../java/build/Proxy.java:80
#, java-format
msgid ""
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
"subscriptions{3} to your addressbook."
msgstr "이 페이지가 자주 보이세요? See {0}the FAQ{1} for help in {2}adding some subscriptions{3} to your addressbook."
#: ../java/build/Proxy.java:89
msgid ""
"The website was not reachable, because it uses encryption options that are "
"not supported by your I2P or Java version."
msgstr "웹사이트에 접속할 수 없습니다. 해당 사이트의 암호화 설정이 사용중인 I2P, JAVA와 호환되지 않습니다."
#: ../java/build/Proxy.java:90 ../java/build/Proxy.java:200
msgid "Could not connect to the following destination:"
msgstr "다음 목적지에 도달할 수 없습니다:"
#: ../java/build/Proxy.java:91 ../java/build/Proxy.java:97
#: ../java/build/Proxy.java:168 ../java/build/Proxy.java:174
msgid "Connection Reset"
msgstr "연결 리셋"
#: ../java/build/Proxy.java:98
msgid "The connection to the website was reset while the page was loading."
msgstr "페이지가 로딩되는 동안 연결이 리셋됬습니다."
#: ../java/build/Proxy.java:99
msgid ""
"The website could be temporarily unavailable, too busy, or it has blocked "
"your access."
msgstr "웹사이트에 일시적으로 접속할 수 없습니다. 접속이 폭주하고 있거나, 사용자를 차단했을 수 있습니다."
#: ../java/build/Proxy.java:102 ../java/build/Proxy.java:108
msgid "Warning: Invalid Destination"
msgstr "경고: 비정상적인 목적지"
#: ../java/build/Proxy.java:109
msgid ""
"The website destination specified was not valid, or was otherwise "
"unreachable."
msgstr "연결 목적지가 올바르지 않습니다. 또는 연결이 불가합니다."
#: ../java/build/Proxy.java:110
msgid ""
"Perhaps you pasted in the wrong Base 64 string or the link you are following"
" is bad."
msgstr "올바르지 않은 Base 64 주소를 입력했거나, 타고 들어온 링크가 잘못됬을 수 있습니다."
#: ../java/build/Proxy.java:111
msgid "The I2P host could also be offline."
msgstr "또한 I2P 호스트가 오프라인일 수 있습니다."
#: ../java/build/Proxy.java:114 ../java/build/Proxy.java:120
msgid "Warning: No Outproxy Configured"
msgstr "경고: 아웃프록시 설정안됨"
#: ../java/build/Proxy.java:121
msgid ""
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
"configured."
msgstr "I2P 외부에 접속하려 하셨습니다. 그러나 HTTP 아웃프록시가 설정되있지 않습니다."
#: ../java/build/Proxy.java:122
msgid "Please configure an outproxy in I2PTunnel."
msgstr "I2PTunnel에 있는 아웃프록시를 설정하십시오."
#: ../java/build/Proxy.java:123 ../java/build/Proxy.java:129
msgid "Warning: Destination Key Conflict"
msgstr "경고: 목적지 키 충돌"
#: ../java/build/Proxy.java:130
msgid ""
"The address helper link you followed specifies a different destination key "
"than the entry in your address book."
msgstr "주소록 도우미는 타고들어온 링크가 주소록에 있는 키와 다를 때 도음을 줍니다."
#: ../java/build/Proxy.java:131
msgid ""
"Someone could be trying to impersonate another website, or people have given"
" two websites identical names."
msgstr "누군가 가짜 웹사이트로 접속시키려고 시도중이거나, 혹은 두개의 사이트가 똑같은 이름으로 설정됬을 수 있습니다."
#: ../java/build/Proxy.java:132
msgid ""
"Resolve the conflict by deciding which key you trust, and then either ignore"
" the address helper link, or delete the host entry from your address book "
"and click the address helper link again."
msgstr "두개의 키 중 한개를 선택해 해당 키를 신뢰하도록 설정할 수 있습니다. 혹은 주소록의 호스트 엔트리를 삭제하고 주소록 도우미 링크를 다시 클릭하십시오."
#: ../java/build/Proxy.java:133 ../java/build/Proxy.java:139
msgid "Warning: Bad Address Helper"
msgstr "경고: 올바르지 않은 주소록 도우미"
#: ../java/build/Proxy.java:140
#, java-format
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
msgstr "URL의 헬퍼 키 ({0}i2paddresshelper={1}) 를 분석할 수 없습니다."
#: ../java/build/Proxy.java:141
msgid "It seems to be garbage data, or a mistyped Base 32 address."
msgstr "잘못된 Base 32 주소입니다."
#: ../java/build/Proxy.java:142
msgid ""
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
"or Base 64 key."
msgstr "URL을 확인해 helper key를 올바른 Base 32 / Base 64 주소로 변경하십시오."
#: ../java/build/Proxy.java:150
msgid "The HTTP Outproxy was not found."
msgstr "HTTP 아웃프록시가 발견되지 않았습니다."
#: ../java/build/Proxy.java:151
msgid ""
"It is offline, there is network congestion, or your router is not yet well-"
"integrated with peers."
msgstr "웹사이트가 닫혔거나, 네트워크가 혼잡할 수 있습니다. 혹은 당신의 라우터가 피어들과 충분히 연결되지 않은 상태일 수 있습니다."
#: ../java/build/Proxy.java:155 ../java/build/Proxy.java:161
msgid "Warning: Request Denied"
msgstr "경고: 요청 거부됨"
#: ../java/build/Proxy.java:162
msgid "You attempted to connect to a non-I2P website or location."
msgstr "브라우저가 I2P 웹사이트가 아닌 곳에 연결하려고 시도합니다."
#: ../java/build/Proxy.java:163
msgid "Proxy Authorization Required"
msgstr "프록시 인증요구됨"
#: ../java/build/Proxy.java:164
msgid "I2P HTTP Proxy Authorization Required"
msgstr "I2P HTTP 프록시 인증 요구됨"
#: ../java/build/Proxy.java:165
msgid ""
"This proxy is configured to require a username and password for access."
msgstr "이 프록시는 유저네임 및 패스워드가 요구되도록 설정되었습니다."
#: ../java/build/Proxy.java:166
#, java-format
msgid ""
"Please enter your username and password, or check your {0}router "
"configuration{1} or {2}I2PTunnel configuration{3}."
msgstr "유저네임과 패스워드를 입력해주세요. 또는 {0}라우터 설정{1} 이나 {2}I2P터널 설정{3}을 확인하세요."
#: ../java/build/Proxy.java:167
#, java-format
msgid ""
"To disable authorization, remove the configuration "
"{0}i2ptunnel.proxy.auth=basic{1}, then stop and restart the HTTP Proxy "
"tunnel."
msgstr "인증을 비활성화 하려면 {0}i2ptunnel.proxy.auth=basic{1} 설정을 삭제하고 HTTP 프록시 터널을 종료 후 재시작하세요."
#: ../java/build/Proxy.java:175
msgid "The connection to the proxy was reset."
msgstr "프록시 연결이 리셋되었습니다."
#: ../java/build/Proxy.java:176
msgid ""
"The proxy could be temporarily unavailable, too busy, or it has blocked your"
" access."
msgstr "이 프록시는 일시적으로 사용할 수 없습니다. 접속이 폭주하고 있거나, 사용자를 차단했을 수 있습니다."
#: ../java/build/Proxy.java:180 ../java/build/Proxy.java:186
msgid "Warning: Non-HTTP Protocol"
msgstr "경고: HTTP 프로토콜이 아님"
#: ../java/build/Proxy.java:187
msgid "The request uses a bad protocol."
msgstr "요청이 올바르지 않은 프로토콜을 사용합니다."
#: ../java/build/Proxy.java:188
msgid "The I2P HTTP Proxy supports HTTP and HTTPS requests only."
msgstr "I2P HTTP 프록시는 HTTP와 HTTPS 연결만 지원합니다."
#: ../java/build/Proxy.java:189
msgid "Other protocols such as FTP are not allowed."
msgstr "FTP와 같은 다른 프로토콜은 허용되지 않습니다."
#: ../java/build/Proxy.java:190 ../java/build/Proxy.java:196
msgid "Outproxy Unreachable"
msgstr "아웃프록시에 도달할 수 없습니다."
#: ../java/build/Proxy.java:197
msgid ""
"The HTTP outproxy was not reachable, because it uses encryption options that"
" are not supported by your I2P or Java version."
msgstr "아웃 프록시에 접속할 수 없습니다. 암호화 설정이 사용중인 I2P, JAVA와 호환되지 않습니다."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:640
msgid "This seems to be a bad destination:"
msgstr "잘못된 목적지일 수 있습니다:"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:641
msgid "i2paddresshelper cannot help you with a destination like that!"
msgstr "I2P 주소록 도우미는 해당 목적지와 호환되지 않습니다!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:716
#, java-format
msgid ""
"To visit the destination in your address book, click <a "
"href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
"click <a href=\"{1}\">here</a>."
msgstr "주소록에 있는 목적지를 방문하려면 <a href=\"{0}\">여기</a>를 클릭하세요. 주소록도우미가 제공하는 목적지에 가려면 <a href=\"{1}\">여기</a>를 클릭하세요."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:741
#, java-format
msgid "Destination for {0} in address book"
msgstr "주소록의 {0} 목적지"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:744
msgid "Conflicting address helper destination"
msgstr "주소록 도우미 목적지 충돌"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1169
msgid "Destination lease set not found"
msgstr "목적지 lease set 발견 안됨"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1321
msgid "Host"
msgstr "호스트"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1325
msgid "Base 32"
msgstr "Base 32"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1329
msgid "Destination"
msgstr "목적지"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1335
#, java-format
msgid "Continue to {0} without saving"
msgstr "저장하지 않고 {0} 계속"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1341
#, java-format
msgid "Save {0} to router address book and continue to website"
msgstr "라우터 주소록에 {0} 저장하고 웹사이트로"
#. only blockfile supports multiple books
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1344
#, java-format
msgid "Save {0} to master address book and continue to website"
msgstr "마스터 주소록에 {0} 저장하고 웹사이트로"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1345
#, java-format
msgid "Save {0} to private address book and continue to website"
msgstr "개인 주소록에 {0} 저장하고 웹사이트로"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:171
#, java-format
msgid "Added via address helper from {0}"
msgstr "{0} 으로부터 주소록 도우미를 통해 추가됨"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:173
msgid "Added via address helper"
msgstr "주소록 도우미를 통해 추가됨"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:190
msgid "router"
msgstr "라우터"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:192
msgid "master"
msgstr "마스터"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:194
msgid "private"
msgstr "사설"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:203
#, java-format
msgid "Redirecting to {0}"
msgstr "{0}로 리다이렉트"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:215
#, java-format
msgid "Saved {0} to the {1} addressbook, redirecting now."
msgstr "{1} 주소록에 {0} 저장하고 리다이렉트 하기"
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:216
#, java-format
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
msgstr "{1} 주소록에 {0} 저장하는 것을 실패했습니다. 리다이렉트 합니다."
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:218
msgid "Click here if you are not redirected automatically."
msgstr "자동으로 리다이렉트 되지않으면 여기를 클릭하세요"

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@
# tengo <akin@rbcmail.ru>, 2013
# Aleksey Orekhov <opexob@yandex.ru>, 2013
# Aleksey Vyskubov <viskubov@gmail.com>, 2016
# Alexander Georgievskiy <galeksandrp@gmail.com>, 2016
# sfix <anon-9b36b2e@lycos.com>, 2013
# Dmitriy Mamonov <sassy.but.classic@gmail.com>, 2014
# ducki2p <ducki2p@gmail.com>, 2011
@@ -24,9 +25,9 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-10-06 13:42+0000\n"
"PO-Revision-Date: 2016-10-12 13:22+0000\n"
"Last-Translator: Aleksey Vyskubov <viskubov@gmail.com>\n"
"POT-Creation-Date: 2016-11-30 15:48+0000\n"
"PO-Revision-Date: 2016-12-04 22:58+0000\n"
"Last-Translator: Alexander Georgievskiy <galeksandrp@gmail.com>\n"
"Language-Team: Russian (Russia) (http://www.transifex.com/otf/I2P/language/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -356,21 +357,25 @@ msgid "Variance"
msgstr "Разброс"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361
msgid "0 hop variance (no ransomization, consistent performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:402
msgid "0 hop variance (no randomization, consistent performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:365
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:406
msgid ""
"+ 0-1 hop variance (medium additive ransomization, subtractive performance)"
"+ 0-1 hop variance (medium additive randomization, subtractive performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:369
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:410
msgid ""
"+ 0-2 hop variance (high additive ransomization, subtractive performance)"
"+ 0-2 hop variance (high additive randomization, subtractive performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373
msgid "+/- 0-1 hop variance (standard ransomization, standard performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:414
msgid "+/- 0-1 hop variance (standard randomization, standard performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:377
@@ -640,7 +645,7 @@ msgstr "Добавить в локальную адресную книгу"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:329
msgid "Registration Authentication"
msgstr ""
msgstr "Аутентификация регистрации"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid "Set name with .i2p suffix to enable QR code generation"
@@ -648,25 +653,7 @@ msgstr "Задайте имя, оканчивающееся на .i2p для г
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:337
msgid "Set name with .i2p suffix to enable registration authentication"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:402
msgid "0 hop variance (no randomization, consistent performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:406
msgid ""
"+ 0-1 hop variance (medium additive randomization, subtractive performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:410
msgid ""
"+ 0-2 hop variance (high additive randomization, subtractive performance)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:414
msgid "+/- 0-1 hop variance (standard randomization, standard performance)"
msgstr ""
msgstr "Задайте имя, оканчивающееся на .i2p для аутентификации регистрации"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:505
msgid "Encrypt Leaseset"
@@ -912,7 +899,7 @@ msgstr "Новый клиентский туннель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:102
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:131
msgid "Registration Helper"
msgstr ""
msgstr "Помощник регистрации"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:157
msgid ""
@@ -943,15 +930,15 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:207
msgid "Authentication for adding host"
msgstr ""
msgstr "Аутентификация для добавления хоста"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:211
msgid "Advanced authentication strings"
msgstr ""
msgstr "Расширенные строки аутентификации"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:219
msgid "Authentication for removing host"
msgstr ""
msgstr "Аутентификация для удаления хоста"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:223
#, java-format
@@ -960,7 +947,7 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:249
msgid "Authentication for changing name"
msgstr ""
msgstr "Аутентификация для смены имени"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:260
#, java-format
@@ -975,11 +962,11 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:268
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:297
msgid "Enter old host name below."
msgstr ""
msgstr "Введите старое имя хоста ниже."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:278
msgid "Authentication for adding alias"
msgstr ""
msgstr "Аутентификация для добавления псевдонима"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:289
#, java-format
@@ -988,7 +975,7 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:307
msgid "Authentication for changing destination"
msgstr ""
msgstr "Аутентификация для изменения назначения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:319
#, java-format
@@ -1003,11 +990,11 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:327
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:358
msgid "Enter old destination below."
msgstr ""
msgstr "Введите старое назначение ниже."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:338
msgid "Authentication for adding alternate destination"
msgstr ""
msgstr "Аутентификация для добавления альтернативного назначения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:350
#, java-format
@@ -1016,7 +1003,7 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:369
msgid "Authentication for adding subdomain"
msgstr ""
msgstr "Аутентификация для добавления поддомена"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:382
#, java-format
@@ -1029,7 +1016,7 @@ msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:390
msgid "Enter higher-level domain and destination below."
msgstr ""
msgstr "Введите домен верхнего уровня и назначение ниже."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:406
msgid "Go back and edit the tunnel"
@@ -1037,7 +1024,7 @@ msgstr "Вернитесь и отредактируйте туннель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:416
msgid "Specify old name and destination"
msgstr ""
msgstr "Укажите старое имя и назначение"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:418
msgid "This is only required for advanced authentication."
@@ -1053,7 +1040,7 @@ msgstr "Прежнее имя хоста"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/register_jsp.java:431
msgid "Private Key File for old Destination"
msgstr ""
msgstr "Файл приватного ключа для старого назначения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:123
msgid "I2P Tunnel Manager - Tunnel Creation Wizard"

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@
<!-- only used if not set by a higher build.xml -->
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<target name="compile" depends="depend">
<mkdir dir="./build" />
@@ -71,6 +71,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -28,7 +28,7 @@
<!-- only used if not set by a higher build.xml -->
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<target name="compile" depends="depend">
<mkdir dir="./build" />
@@ -75,6 +75,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -355,3 +355,11 @@
3.2.1 (20 Aug 2015)
- Small bug fixes
3.3.0 (16 Sep 2016)
- Minor core API additions like 'Result.getNumBits', raw bytes for Aztec
- Small changes for Java 9 compatibility
- BS 4.7.6 release with Android API 23 support
- TIFF support in online decoder
- Many small bug fixes, typo fixes and project build improvements

View File

@@ -2,5 +2,4 @@ This is a small portion of zxing, including only what's required
to generate QR codes. There are no modifications.
We've added a build.xml for ant.
Pulled from https://github.com/zxing/zxing on Jan. 4, 2016,
rev 4e3abafe3008e02695f894eccf05f8257fca4ee9 dated Dec. 9, 2015.
https://github.com/zxing/zxing/releases Version 3.3.0 Sept. 16, 2016

View File

@@ -1,5 +1,8 @@
<img align="right" src="https://raw.github.com/wiki/zxing/zxing/zxing-logo.png"/>
##Get Started Developing
To get started, please visit: https://github.com/zxing/zxing/wiki/Getting-Started-Developing
ZXing ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing
library implemented in Java, with ports to other languages.
@@ -50,6 +53,7 @@ library implemented in Java, with ports to other languages.
| [zxing_cpp.rb](https://github.com/glassechidna/zxing_cpp.rb) | bindings for Ruby (not just JRuby), powered by [zxing-cpp](https://github.com/glassechidna/zxing-cpp)
| [python-zxing](https://github.com/oostendo/python-zxing) | bindings for Python
| [ZXing .NET](http://zxingnet.codeplex.com/) | port to .NET and C#, and related Windows platform
| [php-qrcode-detector-decoder](https://github.com/khanamiryan/php-qrcode-detector-decoder) | port to PHP
### Other related third-party open source projects
@@ -61,11 +65,10 @@ library implemented in Java, with ports to other languages.
## Links
* [Online Decoder](http://zxing.org/w/decode.jspx)
* [QR Code Generator](http://zxing.appspot.com/generator)
* [Javadoc](http://zxing.github.io/zxing/apidocs/)
* [Documentation Site](http://zxing.github.io/zxing/)
* [Google+](https://plus.google.com/u/0/b/105889184633382354358/105889184633382354358/posts)
* [Online Decoder](https://zxing.org/w/decode.jspx)
* [QR Code Generator](https://zxing.appspot.com/generator)
* [Javadoc](https://zxing.github.io/zxing/apidocs/)
* [Documentation Site](https://zxing.github.io/zxing/)
## Contacting

View File

@@ -17,17 +17,18 @@
</target>
<!-- only used if not set by a higher build.xml -->
<property name="javac.version" value="1.7" />
<property name="javac.compilerargs7" value="" />
<target name="compile" depends="depend">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./core/src/main/java" debug="true" deprecation="on" source="1.7" target="1.7"
<javac srcdir="./core/src/main/java" debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
destdir="./build/obj" >
<compilerarg line="${javac.compilerargs7}" />
</javac>
<javac srcdir="./javase/src/main/java" debug="true" deprecation="on" source="1.7" target="1.7"
<javac srcdir="./javase/src/main/java" debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
destdir="./build/obj" classpath="./build/obj" >
<compilerarg line="${javac.compilerargs7}" />
@@ -39,7 +40,7 @@
<mkdir dir="./buildTest/obj" />
<javac
srcdir="./test/junit"
debug="true" deprecation="on" source="1.7" target="1.7"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
destdir="./buildTest/obj"
classpath="./build/zxing.jar" >
@@ -75,6 +76,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -95,4 +95,10 @@ public enum EncodeHintType {
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
AZTEC_LAYERS,
/**
* Specifies the exact version of QR code to be encoded.
* (Type {@link Integer}, or {@link String} representation of the integer value).
*/
QR_VERSION,
}

View File

@@ -39,10 +39,8 @@ public abstract class ReaderException extends Exception {
}
// Prevent stack traces from being taken
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
@Override
public final Throwable fillInStackTrace() {
public final synchronized Throwable fillInStackTrace() {
return null;
}

View File

@@ -151,7 +151,7 @@ public final class BitArray implements Cloneable {
* @param end end of range, exclusive
*/
public void setRange(int start, int end) {
if (end < start) {
if (end < start || start < 0 || end > size) {
throw new IllegalArgumentException();
}
if (end == start) {
@@ -163,15 +163,8 @@ public final class BitArray implements Cloneable {
for (int i = firstInt; i <= lastInt; i++) {
int firstBit = i > firstInt ? 0 : start & 0x1F;
int lastBit = i < lastInt ? 31 : end & 0x1F;
int mask;
if (firstBit == 0 && lastBit == 31) {
mask = -1;
} else {
mask = 0;
for (int j = firstBit; j <= lastBit; j++) {
mask |= 1 << j;
}
}
// Ones from firstBit to lastBit, inclusive
int mask = (2 << lastBit) - (1 << firstBit);
bits[i] |= mask;
}
}
@@ -193,10 +186,10 @@ public final class BitArray implements Cloneable {
* @param end end of range, exclusive
* @param value if true, checks that bits in range are set, otherwise checks that they are not set
* @return true iff all bits are set or not set in range, according to value argument
* @throws IllegalArgumentException if end is less than or equal to start
* @throws IllegalArgumentException if end is less than start or the range is not contained in the array
*/
public boolean isRange(int start, int end, boolean value) {
if (end < start) {
if (end < start || start < 0 || end > size) {
throw new IllegalArgumentException();
}
if (end == start) {
@@ -208,15 +201,8 @@ public final class BitArray implements Cloneable {
for (int i = firstInt; i <= lastInt; i++) {
int firstBit = i > firstInt ? 0 : start & 0x1F;
int lastBit = i < lastInt ? 31 : end & 0x1F;
int mask;
if (firstBit == 0 && lastBit == 31) {
mask = -1;
} else {
mask = 0;
for (int j = firstBit; j <= lastBit; j++) {
mask |= 1 << j;
}
}
// Ones from firstBit to lastBit, inclusive
int mask = (2 << lastBit) - (1 << firstBit);
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
@@ -262,11 +248,11 @@ public final class BitArray implements Cloneable {
}
public void xor(BitArray other) {
if (bits.length != other.bits.length) {
if (size != other.size) {
throw new IllegalArgumentException("Sizes don't match");
}
for (int i = 0; i < bits.length; i++) {
// The last byte could be incomplete (i.e. not have 8 bits in
// The last int could be incomplete (i.e. not have 32 bits in
// it) but there is no problem since 0 XOR 0 == 0.
bits[i] ^= other.bits[i];
}
@@ -307,10 +293,10 @@ public final class BitArray implements Cloneable {
public void reverse() {
int[] newBits = new int[bits.length];
// reverse all int's first
int len = ((size-1) / 32);
int len = (size - 1) / 32;
int oldBitsLen = len + 1;
for (int i = 0; i < oldBitsLen; i++) {
long x = (long) bits[i];
long x = bits[i];
x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1);
x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2);
x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4);
@@ -321,16 +307,12 @@ public final class BitArray implements Cloneable {
// now correct the int's if the bit size isn't a multiple of 32
if (size != oldBitsLen * 32) {
int leftOffset = oldBitsLen * 32 - size;
int mask = 1;
for (int i = 0; i < 31 - leftOffset; i++) {
mask = (mask << 1) | 1;
}
int currentInt = (newBits[0] >> leftOffset) & mask;
int currentInt = newBits[0] >>> leftOffset;
for (int i = 1; i < oldBitsLen; i++) {
int nextInt = newBits[i];
currentInt |= nextInt << (32 - leftOffset);
newBits[i - 1] = currentInt;
currentInt = (nextInt >> leftOffset) & mask;
currentInt = nextInt >>> leftOffset;
}
newBits[oldBitsLen - 1] = currentInt;
}
@@ -372,4 +354,4 @@ public final class BitArray implements Cloneable {
return new BitArray(bits.clone(), size);
}
}
}

View File

@@ -102,7 +102,7 @@ public final class BitMatrix implements Cloneable {
// no EOL at end?
if (bitsPos > rowStartPos) {
if(rowLength == -1) {
if (rowLength == -1) {
rowLength = bitsPos - rowStartPos;
} else if (bitsPos - rowStartPos != rowLength) {
throw new IllegalArgumentException("row lengths do not match");
@@ -254,7 +254,7 @@ public final class BitMatrix implements Cloneable {
int height = getHeight();
BitArray topRow = new BitArray(width);
BitArray bottomRow = new BitArray(width);
for (int i = 0; i < (height+1) / 2; i++) {
for (int i = 0; i < (height + 1) / 2; i++) {
topRow = getRow(i, topRow);
bottomRow = getRow(height - 1 - i, bottomRow);
topRow.reverse();
@@ -307,14 +307,11 @@ public final class BitMatrix implements Cloneable {
}
}
int width = right - left;
int height = bottom - top;
if (width < 0 || height < 0) {
if (right < left || bottom < top) {
return null;
}
return new int[] {left, top, width, height};
return new int[] {left, top, right - left + 1, bottom - top + 1};
}
/**
@@ -335,7 +332,7 @@ public final class BitMatrix implements Cloneable {
int theBits = bits[bitsOffset];
int bit = 0;
while ((theBits << (31-bit)) == 0) {
while ((theBits << (31 - bit)) == 0) {
bit++;
}
x += bit;
@@ -419,7 +416,7 @@ public final class BitMatrix implements Cloneable {
* @return string representation of entire matrix utilizing given strings
*/
public String toString(String setString, String unsetString) {
return toString(setString, unsetString, "\n");
return buildToString(setString, unsetString, "\n");
}
/**
@@ -431,6 +428,10 @@ public final class BitMatrix implements Cloneable {
*/
@Deprecated
public String toString(String setString, String unsetString, String lineSeparator) {
return buildToString(setString, unsetString, lineSeparator);
}
private String buildToString(String setString, String unsetString, String lineSeparator) {
StringBuilder result = new StringBuilder(height * (width + 1));
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {

View File

@@ -70,10 +70,10 @@ public final class GenericGF {
x *= 2; // we're assuming the generator alpha is 2
if (x >= size) {
x ^= primitive;
x &= size-1;
x &= size - 1;
}
}
for (int i = 0; i < size-1; i++) {
for (int i = 0; i < size - 1; i++) {
logTable[expTable[i]] = i;
}
// logTable[0] == 0 but this should never be used

View File

@@ -99,7 +99,6 @@ final class GenericGFPoly {
// Just return the x^0 coefficient
return getCoefficient(0);
}
int size = coefficients.length;
if (a == 1) {
// Just the sum of the coefficients
int result = 0;
@@ -109,6 +108,7 @@ final class GenericGFPoly {
return result;
}
int result = coefficients[0];
int size = coefficients.length;
for (int i = 1; i < size; i++) {
result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
}

View File

@@ -66,12 +66,6 @@ final class FormatInformation {
{0x2BED, 0x1F},
};
/**
* Offset i holds the number of 1 bits in the binary representation of i
*/
private static final int[] BITS_SET_IN_HALF_BYTE =
{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
private final ErrorCorrectionLevel errorCorrectionLevel;
private final byte dataMask;
@@ -83,16 +77,7 @@ final class FormatInformation {
}
static int numBitsDiffering(int a, int b) {
a ^= b; // a now has a 1 bit exactly where its bit differs with b's
// Count bits set quickly with a series of lookups:
return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
BITS_SET_IN_HALF_BYTE[(a >>> 4 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 8 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 12 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 16 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 20 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 24 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 28 & 0x0F)];
return Integer.bitCount(a ^ b);
}
/**
@@ -156,7 +141,7 @@ final class FormatInformation {
@Override
public int hashCode() {
return (errorCorrectionLevel.ordinal() << 3) | (int) dataMask;
return (errorCorrectionLevel.ordinal() << 3) | dataMask;
}
@Override

View File

@@ -153,7 +153,7 @@ public final class Version {
int i = alignmentPatternCenters[x] - 2;
for (int y = 0; y < max; y++) {
if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
// No alignment patterns near the three finder paterns
// No alignment patterns near the three finder patterns
continue;
}
bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
@@ -212,7 +212,7 @@ public final class Version {
}
/**
* <p>Encapsualtes the parameters for one error-correction block in one symbol version.
* <p>Encapsulates the parameters for one error-correction block in one symbol version.
* This includes the number of data codewords, and the number of times a block with these
* parameters is used consecutively in the QR code version's format.</p>
*/

View File

@@ -106,21 +106,17 @@ public final class Encoder {
BitArray dataBits = new BitArray();
appendBytes(content, mode, dataBits, encoding);
// Hard part: need to know version to know how many bits length takes. But need to know how many
// bits it takes to know version. First we take a guess at version by assuming version will be
// the minimum, 1:
int provisionalBitsNeeded = headerBits.getSize()
+ mode.getCharacterCountBits(Version.getVersionForNumber(1))
+ dataBits.getSize();
Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);
// Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
int bitsNeeded = headerBits.getSize()
+ mode.getCharacterCountBits(provisionalVersion)
+ dataBits.getSize();
Version version = chooseVersion(bitsNeeded, ecLevel);
Version version;
if (hints != null && hints.containsKey(EncodeHintType.QR_VERSION)) {
int versionNumber = Integer.parseInt(hints.get(EncodeHintType.QR_VERSION).toString());
version = Version.getVersionForNumber(versionNumber);
int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
if (!willFit(bitsNeeded, version, ecLevel)) {
throw new WriterException("Data too big for requested version");
}
} else {
version = recommendVersion(ecLevel, mode, headerBits, dataBits);
}
BitArray headerAndDataBits = new BitArray();
headerAndDataBits.appendBitArray(headerBits);
@@ -161,6 +157,33 @@ public final class Encoder {
return qrCode;
}
/**
* Decides the smallest version of QR code that will contain all of the provided data.
*
* @throws WriterException if the data cannot fit in any version
*/
private static Version recommendVersion(ErrorCorrectionLevel ecLevel,
Mode mode,
BitArray headerBits,
BitArray dataBits) throws WriterException {
// Hard part: need to know version to know how many bits length takes. But need to know how many
// bits it takes to know version. First we take a guess at version by assuming version will be
// the minimum, 1:
int provisionalBitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, Version.getVersionForNumber(1));
Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);
// Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, provisionalVersion);
return chooseVersion(bitsNeeded, ecLevel);
}
private static int calculateBitsNeeded(Mode mode,
BitArray headerBits,
BitArray dataBits,
Version version) {
return headerBits.getSize() + mode.getCharacterCountBits(version) + dataBits.getSize();
}
/**
* @return the code point of the table used in alphanumeric mode or
* -1 if there is no corresponding code in the table.
@@ -246,9 +269,21 @@ public final class Encoder {
}
private static Version chooseVersion(int numInputBits, ErrorCorrectionLevel ecLevel) throws WriterException {
// In the following comments, we use numbers of Version 7-H.
for (int versionNum = 1; versionNum <= 40; versionNum++) {
Version version = Version.getVersionForNumber(versionNum);
if (willFit(numInputBits, version, ecLevel)) {
return version;
}
}
throw new WriterException("Data too big");
}
/**
* @return true if the number of input bits will fit in a code with the specified version and
* error correction level.
*/
private static boolean willFit(int numInputBits, Version version, ErrorCorrectionLevel ecLevel) {
// In the following comments, we use numbers of Version 7-H.
// numBytes = 196
int numBytes = version.getTotalCodewords();
// getNumECBytes = 130
@@ -257,11 +292,7 @@ public final class Encoder {
// getNumDataBytes = 196 - 130 = 66
int numDataBytes = numBytes - numEcBytes;
int totalInputBytes = (numInputBits + 7) / 8;
if (numDataBytes >= totalInputBytes) {
return version;
}
}
throw new WriterException("Data too big");
return numDataBytes >= totalInputBytes;
}
/**
@@ -383,7 +414,7 @@ public final class Encoder {
int size = numDataBytesInBlock[0];
byte[] dataBytes = new byte[size];
bits.toBytes(8*dataBytesOffset, dataBytes, 0, size);
bits.toBytes(8 * dataBytesOffset, dataBytes, 0, size);
byte[] ecBytes = generateECBytes(dataBytes, numEcBytesInBlock[0]);
blocks.add(new BlockPair(dataBytes, ecBytes));

View File

@@ -77,23 +77,23 @@ final class MaskUtil {
byte[] arrayY = array[y]; // We can at least optimize this access
if (x + 6 < width &&
arrayY[x] == 1 &&
arrayY[x + 1] == 0 &&
arrayY[x + 2] == 1 &&
arrayY[x + 3] == 1 &&
arrayY[x + 4] == 1 &&
arrayY[x + 5] == 0 &&
arrayY[x + 6] == 1 &&
arrayY[x + 1] == 0 &&
arrayY[x + 2] == 1 &&
arrayY[x + 3] == 1 &&
arrayY[x + 4] == 1 &&
arrayY[x + 5] == 0 &&
arrayY[x + 6] == 1 &&
(isWhiteHorizontal(arrayY, x - 4, x) || isWhiteHorizontal(arrayY, x + 7, x + 11))) {
numPenalties++;
}
if (y + 6 < height &&
array[y][x] == 1 &&
array[y + 1][x] == 0 &&
array[y + 2][x] == 1 &&
array[y + 3][x] == 1 &&
array[y + 4][x] == 1 &&
array[y + 5][x] == 0 &&
array[y + 6][x] == 1 &&
array[y][x] == 1 &&
array[y + 1][x] == 0 &&
array[y + 2][x] == 1 &&
array[y + 3][x] == 1 &&
array[y + 4][x] == 1 &&
array[y + 5][x] == 0 &&
array[y + 6][x] == 1 &&
(isWhiteVertical(array, x, y - 4, y) || isWhiteVertical(array, x, y + 7, y + 11))) {
numPenalties++;
}
@@ -103,8 +103,10 @@ final class MaskUtil {
}
private static boolean isWhiteHorizontal(byte[] rowArray, int from, int to) {
from = Math.max(from, 0);
to = Math.min(to, rowArray.length);
for (int i = from; i < to; i++) {
if (i >= 0 && i < rowArray.length && rowArray[i] == 1) {
if (rowArray[i] == 1) {
return false;
}
}
@@ -112,8 +114,10 @@ final class MaskUtil {
}
private static boolean isWhiteVertical(byte[][] array, int col, int from, int to) {
from = Math.max(from, 0);
to = Math.min(to, array.length);
for (int i = from; i < to; i++) {
if (i >= 0 && i < array.length && array[i][col] == 1) {
if (array[i][col] == 1) {
return false;
}
}

View File

@@ -271,12 +271,7 @@ final class MatrixUtil {
// - findMSBSet(1) => 1
// - findMSBSet(255) => 8
static int findMSBSet(int value) {
int numDigits = 0;
while (value != 0) {
value >>>= 1;
++numDigits;
}
return numDigits;
return 32 - Integer.numberOfLeadingZeros(value);
}
// Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for "value" using polynomial "poly". The BCH

View File

@@ -1,19 +1,19 @@
Apache Tomcat
Copyright 1999-2015 The Apache Software Foundation
Copyright 1999-2016 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
The Windows Installer is built with the Nullsoft
Scriptable Install Sysem (NSIS), which is
Scriptable Install System (NSIS), which is
open source software. The original software and
related information is available at
http://nsis.sourceforge.net.
Java compilation software for JSP pages is provided by Eclipse,
which is open source software. The original software and
related information is available at
http://www.eclipse.org.
Java compilation software for JSP pages is provided by the Eclipse
JDT Core Batch Compiler component, which is open source software.
The original software and related information is available at
http://www.eclipse.org/jdt/core/.
The original XML Schemas for Java EE Deployment Descriptors:
- javaee_5.xsd

View File

@@ -2,7 +2,7 @@ This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
The Glassfish JSP 2.1 bundled in Jetty 6 is way too old.
Retrieved from the file
apache-tomcat-6.0.44-deployer.tar.gz
apache-tomcat-6.0.48-deployer.tar.gz
minus the following files and directores:

View File

@@ -1,7 +1,7 @@
This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
Retrieved from the file
apache-tomcat-6.0.44.tar.gz
apache-tomcat-6.0.48.tar.gz
containing only a small subset of lib/tomcat-coyote.jar.

View File

@@ -13,16 +13,16 @@
the source in the java/ directory.
-->
<property name="jetty.ver" value="8.1.17.v20150415" />
<property name="jetty.ver" value="8.1.21.v20160908" />
<property name="jetty.base" value="jetty-distribution-${jetty.ver}" />
<property name="jetty.sha1" value="ce7bcd1bdcdac4cf130467f6d55155b9e1517e71" />
<property name="jetty.sha1" value="9780e99e765fd7b9bb1aac8ba2bba374ac039764" />
<property name="jetty.filename" value="${jetty.base}.zip" />
<property name="jetty.url" value="http://download.eclipse.org/jetty/${jetty.ver}/dist/${jetty.filename}" />
<property name="jetty.url" value="http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/${jetty.ver}/${jetty.filename}" />
<property name="verified.filename" value="verified.txt" />
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.6" />
<property name="javac.version" value="1.7" />
<property name="tomcat.lib" value="apache-tomcat-deployer/lib" />
<property name="tomcat.ver" value="6.0.44" />
<property name="tomcat.ver" value="6.0.48" />
<property name="tomcat2.lib" value="apache-tomcat-${tomcat.ver}/lib" />
<property name="tomcat2.lib.small" value="apache-tomcat/lib" />
@@ -225,6 +225,7 @@
<or>
<istrue value="${with-libtomcat6-java}" />
<istrue value="${with-libtomcat7-java}" />
<istrue value="${with-libtomcat8-java}" />
</or>
</condition>
</target>
@@ -339,6 +340,8 @@
<!-- needed by JettyStart for pre-0.7.5 wrapper.config -->
<attribute name="Class-Path" value="jetty-deploy.jar jetty-xml.jar" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -139,7 +139,7 @@ public class RequestWrapper {
String key = e.getKey();
if( key.toLowerCase(Locale.US).compareToIgnoreCase( "content-type") == 0 ) {
String value = e.getValue();
int i = value.indexOf( ";" );
int i = value.indexOf( ';' );
if( i != -1 )
result = value.substring( 0, i );
else

108
apps/jrobin/java/build.xml Normal file
View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="jrobin">
<target name="all" depends="clean, build" />
<target name="build" depends="builddep, jar" />
<target name="builddep">
<!-- run from top level build.xml to get dependencies built -->
</target>
<condition property="depend.available">
<typefound name="depend" />
</condition>
<target name="depend" if="depend.available">
<depend
cache="../../../build"
srcdir="./src"
destdir="./build/obj" >
<classpath>
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>
</depend>
</target>
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.7" />
<target name="compile" depends="depend">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac
srcdir="./src"
debug="true"
deprecation="on"
source="${javac.version}"
target="${javac.version}"
destdir="./build/obj"
includeAntRuntime="false"
includes="**/*.java" >
<compilerarg line="${javac.compilerargs}" />
<classpath>
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>
</javac>
</target>
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="list" />
<arg value="changed" />
<arg value="." />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />
</exec>
</target>
<target name="jar" depends="compile, jarUpToDate, listChangedFiles" unless="jar.uptodate">
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="./build/jrobin.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
<attribute name="Class-Path" value="i2p.jar" />
<attribute name="Implementation-Version" value="1.6.0-1" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
<target name="jarUpToDate">
<uptodate property="jar.uptodate" targetfile="./build/jrobin.jar">
<srcfiles dir= "build/obj" includes="**/*.class" />
</uptodate>
<condition property="shouldListChanges" >
<and>
<not>
<isset property="jar.uptodate" />
</not>
<isset property="mtn.available" />
</and>
</condition>
</target>
<target name="javadoc">
<mkdir dir="./build" />
<mkdir dir="./build/javadoc" />
<javadoc
sourcepath="./src"
classpath="./src"
destdir="./build/javadoc"
packagenames="*"
use="true"
access="package"
splitindex="true" />
</target>
<target name="clean">
<delete dir="./build" />
</target>
<target name="cleandep" depends="clean">
</target>
<target name="distclean" depends="clean">
</target>
</project>

View File

@@ -0,0 +1,781 @@
/**
* Copyright (c) 2006-2016 Julien Gouesse This program is free software; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received
* a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
package engine.misc;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* Helper to deallocate memory on the native heap allocated during the creation
* of a direct byte buffer. It supports numerous virtual machines including
* OpenJDK, Oracle/Sun Java, Android Dalvik Virtual Machine, Apache Harmony and
* GNU Classpath. This class uses the syntax of Java 1.7 but it can work
* correctly with Java 1.4 with a very few minor type changes when using the
* maps and the collections. It relies on lots of implementation details but
* it's robust enough to go on working (except when the implementors
* intentionally use a very general class to store the buffers) despite minor
* naming changes like those that occurred between Java 1.6 and Java 1.7. It
* supports Java 1.9 despite the move of the cleaner from the package sun.misc
* to jdk.internal.ref (in the module java.base). N.B: Releasing the native
* memory of a sliced direct NIO buffer, the one of a direct NIO buffer created
* with JNI or the one of any direct NIO buffer created by the virtual machine
* or by a framework not under your control doesn't prevent the calls to methods
* attempting to access such buffers. Those calls can throw an exception or
* crash the virtual machine depending on the implementations.
*
* @author Julien Gouesse
*/
public class DeallocationHelper {
private final Log logger = I2PAppContext.getGlobalContext().logManager().getLog(DeallocationHelper.class);
/**
* tool responsible for releasing the native memory of a deallocatable byte
* buffer
*/
public static abstract class Deallocator {
protected final Log logger = I2PAppContext.getGlobalContext().logManager().getLog(DeallocationHelper.class);
public Deallocator() {
super();
}
/**
* releases the native memory of a deallocatable byte buffer
*
* @param directByteBuffer
* deallocatable byte buffer
*
* @return <code>true</code> if the deallocation is successful,
* otherwise <code>false</code>
*/
public abstract boolean run(final ByteBuffer directByteBuffer);
}
public static class OracleSunOpenJdkDeallocator extends Deallocator {
private Method directByteBufferCleanerMethod;
private Method cleanerCleanMethod;
public OracleSunOpenJdkDeallocator() {
super();
try {
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
directByteBufferCleanerMethod = directByteBufferClass.getDeclaredMethod("cleaner");
/**
* The return type is sun.misc.Cleaner in Java <= 1.8,
* jdk.internal.ref.Cleaner in Java >= 1.9. Only the latter
* implements the Runnable interface.
*/
final Class<?> cleanerClass = directByteBufferCleanerMethod.getReturnType();
if (Runnable.class.isAssignableFrom(cleanerClass)) {
cleanerCleanMethod = Runnable.class.getDeclaredMethod("run");
} else {
cleanerCleanMethod = cleanerClass.getDeclaredMethod("clean");
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.warn(
"The initialization of the deallocator for Oracle Java, Sun Java and OpenJDK has failed", e);
}
}
@Override
public boolean run(final ByteBuffer directByteBuffer) {
boolean success = false;
if (directByteBufferCleanerMethod != null && cleanerCleanMethod != null) {
final boolean directByteBufferCleanerMethodWasAccessible = directByteBufferCleanerMethod.isAccessible();
final boolean cleanerCleanMethodWasAccessible = cleanerCleanMethod.isAccessible();
try {
// according to the Java documentation, by default, a reflected object is not accessible
directByteBufferCleanerMethod.setAccessible(true);
final Object cleaner = directByteBufferCleanerMethod.invoke(directByteBuffer);
if (cleaner != null) {
cleanerCleanMethod.setAccessible(true);
cleanerCleanMethod.invoke(cleaner);
success = true;
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferCleanerMethod.setAccessible(directByteBufferCleanerMethodWasAccessible);
cleanerCleanMethod.setAccessible(cleanerCleanMethodWasAccessible);
}
}
return (success);
}
}
public static class AndroidDeallocator extends Deallocator {
private Method directByteBufferFreeMethod;
public AndroidDeallocator() {
super();
try {
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.warn("The initialization of the deallocator for Android has failed", e);
}
}
@Override
public boolean run(final ByteBuffer directByteBuffer) {
boolean success = false;
if (directByteBufferFreeMethod != null) {
final boolean directByteBufferFreeMethodWasAccessible = directByteBufferFreeMethod.isAccessible();
try {
directByteBufferFreeMethod.setAccessible(true);
directByteBufferFreeMethod.invoke(directByteBuffer);
success = true;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
}
}
return (success);
}
}
public static class GnuClasspathDeallocator extends Deallocator {
private Method vmDirectByteBufferFreeMethod;
private Field bufferAddressField;
public GnuClasspathDeallocator() {
super();
try {
final Class<?> vmDirectByteBufferClass = Class.forName("java.nio.VMDirectByteBuffer");
final Class<?> gnuClasspathPointerClass = Class.forName("gnu.classpath.Pointer");
vmDirectByteBufferFreeMethod = vmDirectByteBufferClass.getDeclaredMethod("free",
gnuClasspathPointerClass);
bufferAddressField = Buffer.class.getDeclaredField("address");
} catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException e) {
logger.warn("The initialization of the deallocator for GNU Classpath has failed", e);
}
}
@Override
public boolean run(final ByteBuffer directByteBuffer) {
boolean success = false;
if (vmDirectByteBufferFreeMethod != null && bufferAddressField != null) {
final boolean bufferAddressFieldWasAccessible = bufferAddressField.isAccessible();
final boolean vmDirectByteBufferFreeMethodWasAccessible = vmDirectByteBufferFreeMethod.isAccessible();
try {
bufferAddressField.setAccessible(true);
final Object address = bufferAddressField.get(directByteBuffer);
if (address != null) {
vmDirectByteBufferFreeMethod.setAccessible(true);
vmDirectByteBufferFreeMethod.invoke(null, address);
success = true;
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
bufferAddressField.setAccessible(bufferAddressFieldWasAccessible);
vmDirectByteBufferFreeMethod.setAccessible(vmDirectByteBufferFreeMethodWasAccessible);
}
}
return (success);
}
}
public static class ApacheHarmonyDeallocator extends Deallocator {
private Method directByteBufferFreeMethod;
public ApacheHarmonyDeallocator() {
super();
try {
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.warn("The initialization of the deallocator for Apache Harmony has failed", e);
}
}
@Override
public boolean run(final ByteBuffer directByteBuffer) {
boolean success = false;
if (directByteBufferFreeMethod != null) {
final boolean directByteBufferFreeMethodWasAccessible = directByteBufferFreeMethod.isAccessible();
try {
directByteBufferFreeMethod.setAccessible(true);
directByteBufferFreeMethod.invoke(directByteBuffer);
success = true;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
}
}
return (success);
}
}
private Map<Class<?>, Field> attachmentOrByteBufferFieldMap;
private Set<Class<?>> deallocatableBufferClassSet;
private Deallocator deallocator;
/**
* Default constructor
*/
public DeallocationHelper() {
this(false);
}
/**
* Main constructor
*
* @param ignoreClassesAndFieldsHints
* <code>true</code> if the known implementation details should
* be ignored when looking for the classes and the fields used
* for the native memory of the direct buffers (they are then
* fully recomputed at runtime which is slower but safer),
* otherwise <code>false</code>
*/
public DeallocationHelper(final boolean ignoreClassesAndFieldsHints) {
super();
final List<Buffer> buffersToDelete = new ArrayList<>();
/**
* builds the map used to determine the names of the fields containing
* the direct byte buffers. The direct read only buffers and the sliced
* buffers and the direct buffers for other primitive types than bytes
* store their data into some direct byte buffers. Those direct byte
* buffers often are the only one accessing directly to the native
* memory. That's why it's necessary to find them when a developer
* passes a direct NIO buffer. The code below relies on numerous
* implementation details found in some classes not available in the
* public APIs, it's used to find the fields faster in most of the
* cases. The class names haven't changed since Java 1.4 unlike a few
* field names.
*/
final Map<String, String> attachmentOrByteBufferFieldNameMap = new HashMap<>();
final String javaVendor = System.getProperty("java.vendor");
final String javaVersion = System.getProperty("java.version");
if (!ignoreClassesAndFieldsHints) {
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation")) {
final String java14to16DirectBufferAttachmentFieldName = "viewedBuffer";
final String java17to19DirectBufferAttachmentFieldName = "att";
final String byteBufferAsNonByteBufferByteBufferFieldName = "bb";
final String[] directBufferClassnames = new String[] { "java.nio.DirectByteBuffer",
"java.nio.DirectByteBufferR", "java.nio.DirectCharBufferRS", "java.nio.DirectCharBufferRU",
"java.nio.DirectCharBufferS", "java.nio.DirectCharBufferU", "java.nio.DirectDoubleBufferRS",
"java.nio.DirectDoubleBufferRU", "java.nio.DirectDoubleBufferS", "java.nio.DirectDoubleBufferU",
"java.nio.DirectFloatBufferRS", "java.nio.DirectFloatBufferRU", "java.nio.DirectFloatBufferS",
"java.nio.DirectFloatBufferU", "java.nio.DirectIntBufferRS", "java.nio.DirectIntBufferRU",
"java.nio.DirectIntBufferS", "java.nio.DirectIntBufferU", "java.nio.DirectLongBufferRS",
"java.nio.DirectLongBufferRU", "java.nio.DirectLongBufferS", "java.nio.DirectLongBufferU",
"java.nio.DirectShortBufferRS", "java.nio.DirectShortBufferRU", "java.nio.DirectShortBufferS",
"java.nio.DirectShortBufferU" };
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.ByteBufferAsCharBufferB",
"java.nio.ByteBufferAsCharBufferL", "java.nio.ByteBufferAsCharBufferRB",
"java.nio.ByteBufferAsCharBufferRL", "java.nio.ByteBufferAsDoubleBufferB",
"java.nio.ByteBufferAsDoubleBufferL", "java.nio.ByteBufferAsDoubleBufferRB",
"java.nio.ByteBufferAsDoubleBufferRL", "java.nio.ByteBufferAsFloatBufferB",
"java.nio.ByteBufferAsFloatBufferL", "java.nio.ByteBufferAsFloatBufferRB",
"java.nio.ByteBufferAsFloatBufferRL", "java.nio.ByteBufferAsIntBufferB",
"java.nio.ByteBufferAsIntBufferL", "java.nio.ByteBufferAsIntBufferRB",
"java.nio.ByteBufferAsIntBufferRL", "java.nio.ByteBufferAsLongBufferB",
"java.nio.ByteBufferAsLongBufferL", "java.nio.ByteBufferAsLongBufferRB",
"java.nio.ByteBufferAsLongBufferRL", "java.nio.ByteBufferAsShortBufferB",
"java.nio.ByteBufferAsShortBufferL", "java.nio.ByteBufferAsShortBufferRB",
"java.nio.ByteBufferAsShortBufferRL" };
final String[] javaVersionElements = System.getProperty("java.version").split("\\.");
int indexOfEarlyAccessSuffix = javaVersionElements[0].lastIndexOf("-ea");
if (indexOfEarlyAccessSuffix != -1) {
// drops the "-ea" suffix from the major version number for
// an early access build
javaVersionElements[0] = javaVersionElements[0].substring(0, indexOfEarlyAccessSuffix);
} else {
indexOfEarlyAccessSuffix = javaVersionElements[0].lastIndexOf("-internal");
if (indexOfEarlyAccessSuffix != -1) {
// drops the "-internal" suffix from the major version number for
// an early access build (Ubuntu)
javaVersionElements[0] = javaVersionElements[0].substring(0, indexOfEarlyAccessSuffix);
}
}
final int major, minor;
if (javaVersionElements.length >= 2) {
major = Integer.parseInt(javaVersionElements[0]);
minor = Integer.parseInt(javaVersionElements[1]);
} else {
major = 1;
minor = Integer.parseInt(javaVersionElements[0]);
}
final String directBufferAttachmentFieldName;
if (minor == 1 && major <= 6)
directBufferAttachmentFieldName = java14to16DirectBufferAttachmentFieldName;
else
directBufferAttachmentFieldName = java17to19DirectBufferAttachmentFieldName;
for (final String directBufferClassname : directBufferClassnames)
attachmentOrByteBufferFieldNameMap.put(directBufferClassname, directBufferAttachmentFieldName);
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames)
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname,
byteBufferAsNonByteBufferByteBufferFieldName);
} else if (javaVendor.equals("The Android Project")) {
final String byteBufferAsNonByteBufferByteBufferFieldName = "byteBuffer";
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.ByteBufferAsCharBuffer",
"java.nio.ByteBufferAsDoubleBuffer", "java.nio.ByteBufferAsFloatBuffer",
"java.nio.ByteBufferAsIntBuffer", "java.nio.ByteBufferAsLongBuffer",
"java.nio.ByteBufferAsShortBuffer" };
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames)
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname,
byteBufferAsNonByteBufferByteBufferFieldName);
} else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc.")) {
final String byteBufferAsNonByteBufferByteBufferFieldName = "bb";
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.CharViewBufferImpl",
"java.nio.DoubleViewBufferImpl", "java.nio.FloatViewBufferImpl", "java.nio.IntViewBufferImpl",
"java.nio.LongViewBufferImpl", "java.nio.ShortViewBufferImpl" };
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames)
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname,
byteBufferAsNonByteBufferByteBufferFieldName);
} else if (javaVendor.contains("Apache")) {
final String byteBufferAsNonByteBufferByteBufferFieldName = "byteBuffer";
final String[] byteBufferAsNonByteBufferClassnames = new String[] { "java.nio.CharToByteBufferAdapter",
"java.nio.DoubleToByteBufferAdapter", "java.nio.FloatToByteBufferAdapter",
"java.nio.IntToByteBufferAdapter", "java.nio.LongToByteBufferAdapter",
"java.nio.ShortToByteBufferAdapter" };
for (final String byteBufferAsNonByteBufferClassname : byteBufferAsNonByteBufferClassnames)
attachmentOrByteBufferFieldNameMap.put(byteBufferAsNonByteBufferClassname,
byteBufferAsNonByteBufferByteBufferFieldName);
} else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
} else if (javaVendor.contains("IBM")) {// TODO J9
}
}
// checks if these classes are in the class library
if (!attachmentOrByteBufferFieldNameMap.isEmpty()) {
final List<String> classnamesToRemove = new ArrayList<>();
for (final String classname : attachmentOrByteBufferFieldNameMap.keySet())
try {
Class.forName(classname);
} catch (ClassNotFoundException cnfe) {
classnamesToRemove.add(classname);
}
for (final String classnameToRemove : classnamesToRemove)
attachmentOrByteBufferFieldNameMap.remove(classnameToRemove);
}
// builds the map used to determine the fields containing the direct
// byte buffers
attachmentOrByteBufferFieldMap = new HashMap<>();
if (!attachmentOrByteBufferFieldNameMap.isEmpty())
for (final Entry<String, String> attachmentOrByteBufferFieldNameEntry : attachmentOrByteBufferFieldNameMap
.entrySet()) {
final String classname = attachmentOrByteBufferFieldNameEntry.getKey();
final String fieldname = attachmentOrByteBufferFieldNameEntry.getValue();
try {
final Class<?> bufferClass = Class.forName(classname);
Field bufferField = null;
Class<?> bufferIntermediaryClass = bufferClass;
final List<Class<?>> intermediaryClassWithoutBufferList = new ArrayList<>();
while (bufferIntermediaryClass != null) {
try {
bufferField = bufferIntermediaryClass.getDeclaredField(fieldname);
} catch (NoSuchFieldException nsfe) {
if (!bufferIntermediaryClass.equals(Object.class)
&& !bufferIntermediaryClass.equals(Buffer.class))
intermediaryClassWithoutBufferList.add(bufferIntermediaryClass);
}
bufferIntermediaryClass = bufferIntermediaryClass.getSuperclass();
}
if (bufferField == null) {
final String superClassesMsg;
if (intermediaryClassWithoutBufferList.isEmpty())
superClassesMsg = "";
else if (intermediaryClassWithoutBufferList.size() == 1)
superClassesMsg = " and in its super class "
+ intermediaryClassWithoutBufferList.get(0).getName();
else {
final StringBuilder builder = new StringBuilder();
builder.append(" and in its super classes");
int classIndex = 0;
for (final Class<?> intermediaryClassWithoutBuffer : intermediaryClassWithoutBufferList) {
builder.append(' ');
builder.append(intermediaryClassWithoutBuffer.getName());
if (classIndex < intermediaryClassWithoutBufferList.size() - 1)
builder.append(',');
classIndex++;
}
superClassesMsg = builder.toString();
}
logger.warn("The field " + fieldname + " hasn't been found in the class " + classname
+ superClassesMsg);
} else {// the field has been found, stores it into the map
attachmentOrByteBufferFieldMap.put(bufferClass, bufferField);
}
} catch (ClassNotFoundException cnfe) {// TODO The Java version
// isn't very useful
// under
// Android as it is
// always zero, rather
// use
// android.os.Build.VERSION.RELEASE
// to show something
// meaningful supported
// since the API level 1
final String msg = "The class " + classname
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
}
// if a known implementation has drastically changed or if the current
// implementation is unknown
if (attachmentOrByteBufferFieldNameMap.isEmpty()) {// detects everything
// with the
// reflection API
// creates all
// possible kinds of
// direct NIO buffer
// that can contain
// buffers (sliced
// buffers and views)
final ByteBuffer slicedBigEndianReadOnlyDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2)
.order(ByteOrder.BIG_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice()
.asReadOnlyBuffer();
final ByteBuffer slicedBigEndianReadWriteDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2)
.order(ByteOrder.BIG_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice();
final CharBuffer bigEndianReadOnlyDirectCharBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asCharBuffer();
final CharBuffer bigEndianReadWriteDirectCharBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asCharBuffer();
final DoubleBuffer bigEndianReadOnlyDirectDoubleBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asDoubleBuffer();
final DoubleBuffer bigEndianReadWriteDirectDoubleBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asDoubleBuffer();
final FloatBuffer bigEndianReadOnlyDirectFloatBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asFloatBuffer();
final FloatBuffer bigEndianReadWriteDirectFloatBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asFloatBuffer();
final IntBuffer bigEndianReadOnlyDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN)
.asReadOnlyBuffer().asIntBuffer();
final IntBuffer bigEndianReadWriteDirectIntBuffer = ByteBuffer.allocateDirect(1).order(ByteOrder.BIG_ENDIAN)
.asIntBuffer();
final LongBuffer bigEndianReadOnlyDirectLongBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asLongBuffer();
final LongBuffer bigEndianReadWriteDirectLongBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asLongBuffer();
final ShortBuffer bigEndianReadOnlyDirectShortBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer().asShortBuffer();
final ShortBuffer bigEndianReadWriteDirectShortBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.BIG_ENDIAN).asShortBuffer();
final ByteBuffer slicedLittleEndianReadOnlyDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2)
.order(ByteOrder.LITTLE_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice()
.asReadOnlyBuffer();
final ByteBuffer slicedLittleEndianReadWriteDirectByteBuffer = ((ByteBuffer) ByteBuffer.allocateDirect(2)
.order(ByteOrder.LITTLE_ENDIAN).put((byte) 0).put((byte) 0).position(1).limit(2)).slice();
final CharBuffer littleEndianReadOnlyDirectCharBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asCharBuffer();
final CharBuffer littleEndianReadWriteDirectCharBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
final DoubleBuffer littleEndianReadOnlyDirectDoubleBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asDoubleBuffer();
final DoubleBuffer littleEndianReadWriteDirectDoubleBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
final FloatBuffer littleEndianReadOnlyDirectFloatBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asFloatBuffer();
final FloatBuffer littleEndianReadWriteDirectFloatBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
final IntBuffer littleEndianReadOnlyDirectIntBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asIntBuffer();
final IntBuffer littleEndianReadWriteDirectIntBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
final LongBuffer littleEndianReadOnlyDirectLongBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asLongBuffer();
final LongBuffer littleEndianReadWriteDirectLongBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
final ShortBuffer littleEndianReadOnlyDirectShortBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().asShortBuffer();
final ShortBuffer littleEndianReadWriteDirectShortBuffer = ByteBuffer.allocateDirect(1)
.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
final List<Buffer> buffers = new ArrayList<>();
buffers.add(slicedBigEndianReadOnlyDirectByteBuffer);
buffers.add(slicedBigEndianReadWriteDirectByteBuffer);
buffers.add(bigEndianReadOnlyDirectCharBuffer);
buffers.add(bigEndianReadWriteDirectCharBuffer);
buffers.add(bigEndianReadOnlyDirectDoubleBuffer);
buffers.add(bigEndianReadWriteDirectDoubleBuffer);
buffers.add(bigEndianReadOnlyDirectFloatBuffer);
buffers.add(bigEndianReadWriteDirectFloatBuffer);
buffers.add(bigEndianReadOnlyDirectIntBuffer);
buffers.add(bigEndianReadWriteDirectIntBuffer);
buffers.add(bigEndianReadOnlyDirectLongBuffer);
buffers.add(bigEndianReadWriteDirectLongBuffer);
buffers.add(bigEndianReadOnlyDirectShortBuffer);
buffers.add(bigEndianReadWriteDirectShortBuffer);
buffers.add(slicedLittleEndianReadOnlyDirectByteBuffer);
buffers.add(slicedLittleEndianReadWriteDirectByteBuffer);
buffers.add(littleEndianReadOnlyDirectCharBuffer);
buffers.add(littleEndianReadWriteDirectCharBuffer);
buffers.add(littleEndianReadOnlyDirectDoubleBuffer);
buffers.add(littleEndianReadWriteDirectDoubleBuffer);
buffers.add(littleEndianReadOnlyDirectFloatBuffer);
buffers.add(littleEndianReadWriteDirectFloatBuffer);
buffers.add(littleEndianReadOnlyDirectIntBuffer);
buffers.add(littleEndianReadWriteDirectIntBuffer);
buffers.add(littleEndianReadOnlyDirectLongBuffer);
buffers.add(littleEndianReadWriteDirectLongBuffer);
buffers.add(littleEndianReadOnlyDirectShortBuffer);
buffers.add(littleEndianReadWriteDirectShortBuffer);
// gets the fields to access the contained buffers
for (Buffer buffer : buffers) {
final Class<?> bufferClass = buffer.getClass();
if (!attachmentOrByteBufferFieldMap.containsKey(bufferClass)) {
Field bufferField = null;
Class<?> bufferIntermediaryClass = bufferClass;
while (bufferIntermediaryClass != null && bufferField == null) {
for (final Field field : bufferIntermediaryClass.getDeclaredFields()) {
final boolean fieldWasAccessible = field.isAccessible();
try {
field.setAccessible(true);
final Object fieldValue = field.get(buffer);
if (fieldValue != null && fieldValue instanceof Buffer) {
bufferField = field;
break;
}
} catch (IllegalAccessException iae) {
logger.warn("Cannot access the field " + field.getName()
+ " of the class " + bufferIntermediaryClass.getName(), iae);
} finally {
field.setAccessible(fieldWasAccessible);
}
}
bufferIntermediaryClass = bufferIntermediaryClass.getSuperclass();
}
if (bufferField != null)
attachmentOrByteBufferFieldMap.put(bufferClass, bufferField);
}
}
// cleans the mess
buffersToDelete.addAll(buffers);
}
// builds the set of classes whose instances can be deallocated
deallocatableBufferClassSet = new HashSet<>();
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation")
|| javaVendor.equals("The Android Project")) {
Class<?> directByteBufferClass = null;
final String directByteBufferClassName = "java.nio.DirectByteBuffer";
try {
directByteBufferClass = Class.forName(directByteBufferClassName);
} catch (ClassNotFoundException cnfe) {
final String msg = "The class " + directByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
if (directByteBufferClass != null)
deallocatableBufferClassSet.add(directByteBufferClass);
} else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc.")) {
Class<?> readOnlyDirectByteBufferClass = null;
final String readOnlyDirectByteBufferClassName = "java.nio.DirectByteBufferImpl.ReadOnly";
try {
readOnlyDirectByteBufferClass = Class.forName(readOnlyDirectByteBufferClassName);
} catch (ClassNotFoundException cnfe) {
final String msg = "The class " + readOnlyDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
if (readOnlyDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
Class<?> readWriteDirectByteBufferClass = null;
final String readWriteDirectByteBufferClassName = "java.nio.DirectByteBufferImpl.ReadWrite";
try {
readWriteDirectByteBufferClass = Class.forName(readWriteDirectByteBufferClassName);
} catch (ClassNotFoundException cnfe) {
final String msg = "The class " + readWriteDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
if (readWriteDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
} else if (javaVendor.contains("Apache")) {
Class<?> readOnlyDirectByteBufferClass = null;
final String readOnlyDirectByteBufferClassName = "java.nio.ReadOnlyDirectByteBuffer";
try {
readOnlyDirectByteBufferClass = Class.forName(readOnlyDirectByteBufferClassName);
} catch (ClassNotFoundException cnfe) {
final String msg = "The class " + readOnlyDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
if (readOnlyDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
Class<?> readWriteDirectByteBufferClass = null;
final String readWriteDirectByteBufferClassName = "java.nio.ReadWriteDirectByteBuffer";
try {
readWriteDirectByteBufferClass = Class.forName(readWriteDirectByteBufferClassName);
} catch (ClassNotFoundException cnfe) {
final String msg = "The class " + readWriteDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.warn(msg, cnfe);
}
if (readWriteDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
} else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
} else if (javaVendor.contains("IBM")) {// TODO J9
}
// if there is no known implementation class of the direct byte buffers
if (deallocatableBufferClassSet.isEmpty()) {// creates a read write
// direct byte buffer
final ByteBuffer dummyReadWriteDirectByteBuffer = ByteBuffer.allocateDirect(1);
// gets its class
final Class<?> readWriteDirectByteBufferClass = dummyReadWriteDirectByteBuffer.getClass();
// stores this class
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
// cleans the mess
buffersToDelete.add(dummyReadWriteDirectByteBuffer);
// creates a read only direct byte buffer
final ByteBuffer dummyReadOnlyDirectByteBuffer = ByteBuffer.allocateDirect(1).asReadOnlyBuffer();
// gets its class
final Class<?> readOnlyDirectByteBufferClass = dummyReadOnlyDirectByteBuffer.getClass();
// stores this class
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
// cleans the mess
buffersToDelete.add(dummyReadOnlyDirectByteBuffer);
}
// builds the deallocator responsible for releasing the native memory of
// a deallocatable byte buffer
if (javaVendor.equals("Sun Microsystems Inc.") || javaVendor.equals("Oracle Corporation"))
deallocator = new OracleSunOpenJdkDeallocator();
else if (javaVendor.equals("The Android Project"))
deallocator = new AndroidDeallocator();
else if (/* javaVendor.equals("Apple Inc.")|| */javaVendor.equals("Free Software Foundation, Inc."))
deallocator = new GnuClasspathDeallocator();
else if (javaVendor.contains("Apache"))
deallocator = new ApacheHarmonyDeallocator();
else if (javaVendor.equals("Jeroen Frijters")) {// TODO IKVM
deallocator = null;
} else if (javaVendor.contains("IBM")) {// TODO J9
deallocator = null;
} else
deallocator = null;
// final cleanup
for (final Buffer bufferToDelete : buffersToDelete)
deallocate(bufferToDelete);
}
public ByteBuffer findDeallocatableBuffer(Buffer buffer) {
final ByteBuffer deallocatableDirectByteBuffer;
// looks only for the direct buffers
if (buffer != null && buffer.isDirect()) {// looks for any contained
// buffer in the passed buffer
final Class<?> bufferClass = buffer.getClass();
final Field attachmentOrByteBufferField = attachmentOrByteBufferFieldMap == null ? null
: attachmentOrByteBufferFieldMap.get(bufferClass);
final Buffer attachmentBufferOrByteBuffer;
if (attachmentOrByteBufferField == null)
attachmentBufferOrByteBuffer = null;
else {
Object attachedObjectOrByteBuffer;
final boolean attachedObjectOrByteBufferFieldWasAccessible = attachmentOrByteBufferField.isAccessible();
try {
attachmentOrByteBufferField.setAccessible(true);
attachedObjectOrByteBuffer = attachmentOrByteBufferField.get(buffer);
} catch (IllegalArgumentException | IllegalAccessException iae) {
attachedObjectOrByteBuffer = null;
} finally {
attachmentOrByteBufferField.setAccessible(attachedObjectOrByteBufferFieldWasAccessible);
}
if (attachedObjectOrByteBuffer instanceof Buffer)
attachmentBufferOrByteBuffer = (Buffer) attachedObjectOrByteBuffer;
else
attachmentBufferOrByteBuffer = null;
}
// if there is no buffer inside the buffer given in input
if (attachmentBufferOrByteBuffer == null) {// if it's a direct byte
// buffer and if it's an
// instance of
// a deallocatable buffer
// class
if (buffer instanceof ByteBuffer && deallocatableBufferClassSet.contains(bufferClass))
deallocatableDirectByteBuffer = (ByteBuffer) buffer;
else {// it's not a byte buffer or it's not a
// deallocatable buffer
deallocatableDirectByteBuffer = null;
final String bufferClassName = bufferClass.getName();
logger.warn("No deallocatable buffer has been found for an instance of the class "
+ bufferClassName + " whereas it is a direct NIO buffer");
}
} else {// the passed buffer contains another buffer, looks for a
// deallocatable buffer inside it
deallocatableDirectByteBuffer = findDeallocatableBuffer(attachmentBufferOrByteBuffer);
}
} else {// there is no need to clean the heap based buffers
deallocatableDirectByteBuffer = null;
}
return deallocatableDirectByteBuffer;
}
public void deallocate(final Buffer buffer) {
if (deallocator != null) {
final ByteBuffer deallocatableBuffer = findDeallocatableBuffer(buffer);
if (deallocatableBuffer != null)
deallocator.run(deallocatableBuffer);
}
}
public Deallocator getDeallocator() {
return (deallocator);
}
public void setDeallocator(Deallocator deallocator) {
this.deallocator = deallocator;
}
public Map<Class<?>, Field> getAttachmentOrByteBufferFieldMap() {
return (attachmentOrByteBufferFieldMap);
}
public void setAttachmentOrByteBufferFieldMap(Map<Class<?>, Field> attachmentOrByteBufferFieldMap) {
this.attachmentOrByteBufferFieldMap = attachmentOrByteBufferFieldMap;
}
public Set<Class<?>> getDeallocatableBufferClassSet() {
return (deallocatableBufferClassSet);
}
public void setDeallocatableBufferClassSet(Set<Class<?>> deallocatableBufferClassSet) {
this.deallocatableBufferClassSet = deallocatableBufferClassSet;
}
}

View File

@@ -0,0 +1,181 @@
/*******************************************************************************
* Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
* Copyright (c) 2011 The OpenNMS Group, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*******************************************************************************/
package org.jrobin.core;
/**
* Class to represent single archive definition within the RRD.
* Archive definition consists of the following four elements:
* <p>
* <ul>
* <li>consolidation function
* <li>X-files factor
* <li>number of steps
* <li>number of rows.
* </ul>
* <p>
* For the complete explanation of all archive definition parameters, see RRDTool's
* <a href="../../../../man/rrdcreate.html" target="man">rrdcreate man page</a>.
*
* @author <a href="mailto:saxon@jrobin.org">Sasa Markovic</a>
*/
public class ArcDef implements ConsolFuns {
/**
* array of valid consolidation function names
*/
public static final String CONSOL_FUNS[] = {CF_AVERAGE, CF_MAX, CF_MIN, CF_LAST};
private String consolFun;
private double xff;
private int steps, rows;
/**
* Creates new archive definition object. This object should be passed as argument to
* {@link RrdDef#addArchive(ArcDef) addArchive()} method of
* {@link RrdDb RrdDb} object.
* <p>
* <p>For the complete explanation of all archive definition parameters, see RRDTool's
* <a href="../../../../man/rrdcreate.html" target="man">rrdcreate man page</a></p>
*
* @param consolFun Consolidation function. Allowed values are "AVERAGE", "MIN",
* "MAX" and "LAST" (these string constants are conveniently defined in the
* {@link ConsolFuns} class).
* @param xff X-files factor, between 0 and 1.
* @param steps Number of archive steps.
* @param rows Number of archive rows.
* @throws RrdException Thrown if any parameter has illegal value.
*/
public ArcDef(final String consolFun, final double xff, final int steps, final int rows) throws RrdException {
this.consolFun = consolFun;
this.xff = xff;
this.steps = steps;
this.rows = rows;
validate();
}
/**
* Returns consolidation function.
*
* @return Consolidation function.
*/
public String getConsolFun() {
return consolFun;
}
/**
* Returns the X-files factor.
*
* @return X-files factor value.
*/
public double getXff() {
return xff;
}
/**
* Returns the number of primary RRD steps which complete a single archive step.
*
* @return Number of steps.
*/
public int getSteps() {
return steps;
}
/**
* Returns the number of rows (aggregated values) stored in the archive.
*
* @return Number of rows.
*/
public int getRows() {
return rows;
}
private void validate() throws RrdException {
if (!isValidConsolFun(consolFun)) {
throw new RrdException("Invalid consolidation function specified: " + consolFun);
}
if (Double.isNaN(xff) || xff < 0.0 || xff >= 1.0) {
throw new RrdException("Invalid xff, must be >= 0 and < 1: " + xff);
}
if (steps < 1 || rows < 2) {
throw new RrdException("Invalid steps/rows settings: " + steps + "/" + rows +
". Minimal values allowed are steps=1, rows=2");
}
}
/**
* Returns string representing archive definition (RRDTool format).
*
* @return String containing all archive definition parameters.
*/
public String dump() {
return "RRA:" + consolFun + ":" + xff + ":" + steps + ":" + rows;
}
/**
* Checks if two archive definitions are equal.
* Archive definitions are considered equal if they have the same number of steps
* and the same consolidation function. It is not possible to create RRD with two
* equal archive definitions.
*
* @param obj Archive definition to compare with.
* @return <code>true</code> if archive definitions are equal,
* <code>false</code> otherwise.
*/
public boolean equals(final Object obj) {
if (obj instanceof ArcDef) {
final ArcDef arcObj = (ArcDef) obj;
return consolFun.equals(arcObj.consolFun) && steps == arcObj.steps;
}
return false;
}
public int hashCode() {
return (consolFun.hashCode() + steps) * 53;
}
/**
* Checks if function argument represents valid consolidation function name.
*
* @param consolFun Consolidation function to be checked
* @return <code>true</code> if <code>consolFun</code> is valid consolidation function,
* <code>false</code> otherwise.
*/
public static boolean isValidConsolFun(final String consolFun) {
for (final String cFun : CONSOL_FUNS) {
if (cFun.equals(consolFun)) {
return true;
}
}
return false;
}
void setRows(final int rows) {
this.rows = rows;
}
boolean exactlyEqual(final ArcDef def) {
return consolFun.equals(def.consolFun) && xff == def.xff &&
steps == def.steps && rows == def.rows;
}
public String toString() {
return "ArcDef@" + Integer.toHexString(hashCode()) + "[consolFun=" + consolFun + ",xff=" + xff + ",steps=" + steps + ",rows=" + rows + "]";
}
}

View File

@@ -0,0 +1,140 @@
/*******************************************************************************
* Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
* Copyright (c) 2011 The OpenNMS Group, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*******************************************************************************/
package org.jrobin.core;
import java.io.IOException;
/**
* Class to represent internal RRD archive state for a single datasource. Objects of this
* class are never manipulated directly, it's up to JRobin framework to manage
* internal arcihve states.<p>
*
* @author <a href="mailto:saxon@jrobin.org">Sasa Markovic</a>
*/
public class ArcState implements RrdUpdater {
private Archive parentArc;
private RrdDouble accumValue;
private RrdLong nanSteps;
ArcState(Archive parentArc, boolean shouldInitialize) throws IOException {
this.parentArc = parentArc;
accumValue = new RrdDouble(this);
nanSteps = new RrdLong(this);
if (shouldInitialize) {
Header header = parentArc.getParentDb().getHeader();
long step = header.getStep();
long lastUpdateTime = header.getLastUpdateTime();
long arcStep = parentArc.getArcStep();
long initNanSteps = (Util.normalize(lastUpdateTime, step) -
Util.normalize(lastUpdateTime, arcStep)) / step;
accumValue.set(Double.NaN);
nanSteps.set(initNanSteps);
}
}
String dump() throws IOException {
return "accumValue:" + accumValue.get() + " nanSteps:" + nanSteps.get() + "\n";
}
void setNanSteps(long value) throws IOException {
nanSteps.set(value);
}
/**
* Returns the number of currently accumulated NaN steps.
*
* @return Number of currently accumulated NaN steps.
* @throws IOException Thrown in case of I/O error
*/
public long getNanSteps() throws IOException {
return nanSteps.get();
}
void setAccumValue(double value) throws IOException {
accumValue.set(value);
}
/**
* Returns the value accumulated so far.
*
* @return Accumulated value
* @throws IOException Thrown in case of I/O error
*/
public double getAccumValue() throws IOException {
return accumValue.get();
}
/**
* Returns the Archive object to which this ArcState object belongs.
*
* @return Parent Archive object.
*/
public Archive getParent() {
return parentArc;
}
void appendXml(XmlWriter writer) throws IOException {
writer.startTag("ds");
writer.writeTag("value", accumValue.get());
writer.writeTag("unknown_datapoints", nanSteps.get());
writer.closeTag(); // ds
}
/**
* Copies object's internal state to another ArcState object.
*
* @param other New ArcState object to copy state to
* @throws IOException Thrown in case of I/O error
* @throws RrdException Thrown if supplied argument is not an ArcState object
*/
public void copyStateTo(RrdUpdater other) throws IOException, RrdException {
if (!(other instanceof ArcState)) {
throw new RrdException(
"Cannot copy ArcState object to " + other.getClass().getName());
}
ArcState arcState = (ArcState) other;
arcState.accumValue.set(accumValue.get());
arcState.nanSteps.set(nanSteps.get());
}
/**
* Returns the underlying storage (backend) object which actually performs all
* I/O operations.
*
* @return I/O backend object
*/
public RrdBackend getRrdBackend() {
return parentArc.getRrdBackend();
}
/**
* Required to implement RrdUpdater interface. You should never call this method directly.
*
* @return Allocator object
*/
public RrdAllocator getRrdAllocator() {
return parentArc.getRrdAllocator();
}
public String toString() {
return "ArcState@" + Integer.toHexString(hashCode()) + "[parentArc=" + parentArc + ",accumValue=" + accumValue + ",nanSteps=" + nanSteps + "]";
}
}

View File

@@ -0,0 +1,418 @@
/*******************************************************************************
* Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
* Copyright (c) 2011 The OpenNMS Group, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*******************************************************************************/
package org.jrobin.core;
import java.io.IOException;
/**
* Class to represent single RRD archive in a RRD with its internal state.
* Normally, you don't need methods to manipulate archive objects directly
* because JRobin framework does it automatically for you.
* <p>
* Each archive object consists of three parts: archive definition, archive state objects
* (one state object for each datasource) and round robin archives (one round robin for
* each datasource). API (read-only) is provided to access each of theese parts.
*
* @author <a href="mailto:saxon@jrobin.org">Sasa Markovic</a>
*/
public class Archive implements RrdUpdater, ConsolFuns {
private RrdDb parentDb;
// definition
private RrdString consolFun;
private RrdDouble xff;
private RrdInt steps, rows;
// state
private Robin[] robins;
private ArcState[] states;
Archive(final RrdDb parentDb, final ArcDef arcDef) throws IOException {
final boolean shouldInitialize = arcDef != null;
this.parentDb = parentDb;
consolFun = new RrdString(this, true); // constant, may be cached
xff = new RrdDouble(this);
steps = new RrdInt(this, true); // constant, may be cached
rows = new RrdInt(this, true); // constant, may be cached
if (shouldInitialize) {
consolFun.set(arcDef.getConsolFun());
xff.set(arcDef.getXff());
steps.set(arcDef.getSteps());
rows.set(arcDef.getRows());
}
final int dsCount = parentDb.getHeader().getDsCount();
states = new ArcState[dsCount];
robins = new Robin[dsCount];
final int numRows = rows.get();
for (int i = 0; i < dsCount; i++) {
states[i] = new ArcState(this, shouldInitialize);
robins[i] = new Robin(this, numRows, shouldInitialize);
}
}
// read from XML
Archive(final RrdDb parentDb, final DataImporter reader, final int arcIndex) throws IOException, RrdException,RrdException {
this(parentDb, new ArcDef(
reader.getConsolFun(arcIndex), reader.getXff(arcIndex),
reader.getSteps(arcIndex), reader.getRows(arcIndex)));
final int dsCount = parentDb.getHeader().getDsCount();
for (int i = 0; i < dsCount; i++) {
// restore state
states[i].setAccumValue(reader.getStateAccumValue(arcIndex, i));
states[i].setNanSteps(reader.getStateNanSteps(arcIndex, i));
// restore robins
double[] values = reader.getValues(arcIndex, i);
robins[i].update(values);
}
}
/**
* Returns archive time step in seconds. Archive step is equal to RRD step
* multiplied with the number of archive steps.
*
* @return Archive time step in seconds
* @throws IOException Thrown in case of I/O error.
*/
public long getArcStep() throws IOException {
final long step = parentDb.getHeader().getStep();
return step * steps.get();
}
String dump() throws IOException {
final StringBuffer buffer = new StringBuffer("== ARCHIVE ==\n");
buffer.append("RRA:").append(consolFun.get()).append(":").append(xff.get()).append(":").append(steps.get()).
append(":").append(rows.get()).append("\n");
buffer.append("interval [").append(getStartTime()).append(", ").append(getEndTime()).append("]" + "\n");
for (int i = 0; i < robins.length; i++) {
buffer.append(states[i].dump());
buffer.append(robins[i].dump());
}
return buffer.toString();
}
RrdDb getParentDb() {
return parentDb;
}
public void archive(final int dsIndex, final double value, final long numStepUpdates) throws IOException {
final Robin robin = robins[dsIndex];
final ArcState state = states[dsIndex];
final long step = parentDb.getHeader().getStep();
final long lastUpdateTime = parentDb.getHeader().getLastUpdateTime();
long updateTime = Util.normalize(lastUpdateTime, step) + step;
final long arcStep = getArcStep();
final String consolFunString = consolFun.get();
final int numSteps = steps.get();
final int numRows = rows.get();
final double xffValue = xff.get();
// finish current step
long numUpdates = numStepUpdates;
while (numUpdates > 0) {
accumulate(state, value, consolFunString);
numUpdates--;
if (updateTime % arcStep == 0) {
finalizeStep(state, robin, consolFunString, numSteps, xffValue);
break;
}
else {
updateTime += step;
}
}
// update robin in bulk
final int bulkUpdateCount = (int) Math.min(numUpdates / numSteps, (long) numRows);
robin.bulkStore(value, bulkUpdateCount);
// update remaining steps
final long remainingUpdates = numUpdates % numSteps;
for (long i = 0; i < remainingUpdates; i++) {
accumulate(state, value, consolFunString);
}
}
private void accumulate(final ArcState state, final double value, String consolFunString) throws IOException {
if (Double.isNaN(value)) {
state.setNanSteps(state.getNanSteps() + 1);
}
else {
final double accumValue = state.getAccumValue();
if (consolFunString.equals(CF_MIN)) {
final double minValue = Util.min(accumValue, value);
if (minValue != accumValue) {
state.setAccumValue(minValue);
}
}
else if (consolFunString.equals(CF_MAX)) {
final double maxValue = Util.max(accumValue, value);
if (maxValue != accumValue) {
state.setAccumValue(maxValue);
}
}
else if (consolFunString.equals(CF_LAST)) {
state.setAccumValue(value);
}
else if (consolFunString.equals(CF_AVERAGE)) {
state.setAccumValue(Util.sum(accumValue, value));
}
}
}
private void finalizeStep(final ArcState state, final Robin robin, final String consolFunString, final long numSteps, final double xffValue) throws IOException {
final long nanSteps = state.getNanSteps();
//double nanPct = (double) nanSteps / (double) arcSteps;
double accumValue = state.getAccumValue();
if (nanSteps <= xffValue * numSteps && !Double.isNaN(accumValue)) {
if (consolFunString.equals(CF_AVERAGE)) {
accumValue /= (numSteps - nanSteps);
}
robin.store(accumValue);
} else {
robin.store(Double.NaN);
}
state.setAccumValue(Double.NaN);
state.setNanSteps(0);
}
/**
* Returns archive consolidation function ("AVERAGE", "MIN", "MAX" or "LAST").
*
* @return Archive consolidation function.
* @throws IOException Thrown in case of I/O error.
*/
public String getConsolFun() throws IOException {
return consolFun.get();
}
/**
* Returns archive X-files factor.
*
* @return Archive X-files factor (between 0 and 1).
* @throws IOException Thrown in case of I/O error.
*/
public double getXff() throws IOException {
return xff.get();
}
/**
* Returns the number of archive steps.
*
* @return Number of archive steps.
* @throws IOException Thrown in case of I/O error.
*/
public int getSteps() throws IOException {
return steps.get();
}
/**
* Returns the number of archive rows.
*
* @return Number of archive rows.
* @throws IOException Thrown in case of I/O error.
*/
public int getRows() throws IOException {
return rows.get();
}
/**
* Returns current starting timestamp. This value is not constant.
*
* @return Timestamp corresponding to the first archive row
* @throws IOException Thrown in case of I/O error.
*/
public long getStartTime() throws IOException {
final long endTime = getEndTime();
final long arcStep = getArcStep();
final long numRows = rows.get();
return endTime - (numRows - 1) * arcStep;
}
/**
* Returns current ending timestamp. This value is not constant.
*
* @return Timestamp corresponding to the last archive row
* @throws IOException Thrown in case of I/O error.
*/
public long getEndTime() throws IOException {
final long arcStep = getArcStep();
final long lastUpdateTime = parentDb.getHeader().getLastUpdateTime();
return Util.normalize(lastUpdateTime, arcStep);
}
/**
* Returns the underlying archive state object. Each datasource has its
* corresponding ArcState object (archive states are managed independently
* for each RRD datasource).
*
* @param dsIndex Datasource index
* @return Underlying archive state object
*/
public ArcState getArcState(final int dsIndex) {
return states[dsIndex];
}
/**
* Returns the underlying round robin archive. Robins are used to store actual
* archive values on a per-datasource basis.
*
* @param dsIndex Index of the datasource in the RRD.
* @return Underlying round robin archive for the given datasource.
*/
public Robin getRobin(final int dsIndex) {
return robins[dsIndex];
}
FetchData fetchData(final FetchRequest request) throws IOException, RrdException {
final long arcStep = getArcStep();
final long fetchStart = Util.normalize(request.getFetchStart(), arcStep);
long fetchEnd = Util.normalize(request.getFetchEnd(), arcStep);
if (fetchEnd < request.getFetchEnd()) {
fetchEnd += arcStep;
}
final long startTime = getStartTime();
final long endTime = getEndTime();
String[] dsToFetch = request.getFilter();
if (dsToFetch == null) {
dsToFetch = parentDb.getDsNames();
}
final int dsCount = dsToFetch.length;
final int ptsCount = (int) ((fetchEnd - fetchStart) / arcStep + 1);
final long[] timestamps = new long[ptsCount];
final double[][] values = new double[dsCount][ptsCount];
final long matchStartTime = Math.max(fetchStart, startTime);
final long matchEndTime = Math.min(fetchEnd, endTime);
double[][] robinValues = null;
if (matchStartTime <= matchEndTime) {
// preload robin values
final int matchCount = (int) ((matchEndTime - matchStartTime) / arcStep + 1);
final int matchStartIndex = (int) ((matchStartTime - startTime) / arcStep);
robinValues = new double[dsCount][];
for (int i = 0; i < dsCount; i++) {
final int dsIndex = parentDb.getDsIndex(dsToFetch[i]);
robinValues[i] = robins[dsIndex].getValues(matchStartIndex, matchCount);
}
}
for (int ptIndex = 0; ptIndex < ptsCount; ptIndex++) {
final long time = fetchStart + ptIndex * arcStep;
timestamps[ptIndex] = time;
for (int i = 0; i < dsCount; i++) {
double value = Double.NaN;
if (time >= matchStartTime && time <= matchEndTime) {
// inbound time
final int robinValueIndex = (int) ((time - matchStartTime) / arcStep);
assert robinValues != null;
value = robinValues[i][robinValueIndex];
}
values[i][ptIndex] = value;
}
}
final FetchData fetchData = new FetchData(this, request);
fetchData.setTimestamps(timestamps);
fetchData.setValues(values);
return fetchData;
}
void appendXml(final XmlWriter writer) throws IOException {
writer.startTag("rra");
writer.writeTag("cf", consolFun.get());
writer.writeComment(getArcStep() + " seconds");
writer.writeTag("pdp_per_row", steps.get());
writer.writeTag("xff", xff.get());
writer.startTag("cdp_prep");
for (final ArcState state : states) {
state.appendXml(writer);
}
writer.closeTag(); // cdp_prep
writer.startTag("database");
final long startTime = getStartTime();
for (int i = 0; i < rows.get(); i++) {
final long time = startTime + i * getArcStep();
writer.writeComment(Util.getDate(time) + " / " + time);
writer.startTag("row");
for (final Robin robin : robins) {
writer.writeTag("v", robin.getValue(i));
}
writer.closeTag(); // row
}
writer.closeTag(); // database
writer.closeTag(); // rra
}
/**
* Copies object's internal state to another Archive object.
*
* @param other New Archive object to copy state to
* @throws IOException Thrown in case of I/O error
* @throws RrdException Thrown if supplied argument is not an Archive object
*/
public void copyStateTo(final RrdUpdater other) throws IOException, RrdException {
if (!(other instanceof Archive)) {
throw new RrdException("Cannot copy Archive object to " + other.getClass().getName());
}
final Archive arc = (Archive) other;
if (!arc.consolFun.get().equals(consolFun.get())) {
throw new RrdException("Incompatible consolidation functions");
}
if (arc.steps.get() != steps.get()) {
throw new RrdException("Incompatible number of steps");
}
final int count = parentDb.getHeader().getDsCount();
for (int i = 0; i < count; i++) {
final int j = Util.getMatchingDatasourceIndex(parentDb, i, arc.parentDb);
if (j >= 0) {
states[i].copyStateTo(arc.states[j]);
robins[i].copyStateTo(arc.robins[j]);
}
}
}
/**
* Sets X-files factor to a new value.
*
* @param xff New X-files factor value. Must be &gt;= 0 and &lt; 1.
* @throws RrdException Thrown if invalid value is supplied
* @throws IOException Thrown in case of I/O error
*/
public void setXff(final double xff) throws RrdException, IOException {
if (xff < 0D || xff >= 1D) {
throw new RrdException("Invalid xff supplied (" + xff + "), must be >= 0 and < 1");
}
this.xff.set(xff);
}
/**
* Returns the underlying storage (backend) object which actually performs all
* I/O operations.
*
* @return I/O backend object
*/
public RrdBackend getRrdBackend() {
return parentDb.getRrdBackend();
}
/**
* Required to implement RrdUpdater interface. You should never call this method directly.
*
* @return Allocator object
*/
public RrdAllocator getRrdAllocator() {
return parentDb.getRrdAllocator();
}
public String toString() {
return "Archive@" + Integer.toHexString(hashCode()) + "[parentDb=" + parentDb + ",consolFun=" + consolFun + ",xff=" + xff + ",steps=" + steps + ",rows=" + rows + ",robins=" + robins + ",states=" + states + "]";
}
}

Some files were not shown because too many files have changed in this diff Show More