Commit d52ade48 authored by DrKLO's avatar DrKLO

update to 1.3.2

parent 90d8e8a3
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> <module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/main" />
<output-test url="file://$MODULE_DIR$/build/classes/test" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> <excludeFolder url="file://$MODULE_DIR$/.gradle" />
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
<component name="FacetManager"> <component name="FacetManager">
<facet type="android" name="Android"> <facet type="android" name="Android">
<configuration> <configuration>
<option name="SELECTED_BUILD_VARIANT" value="Debug" /> <option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebug" /> <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" /> <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" /> <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" /> <option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
...@@ -26,37 +26,37 @@ ...@@ -26,37 +26,37 @@
<output url="file://$MODULE_DIR$/build/classes/debug" /> <output url="file://$MODULE_DIR$/build/classes/debug" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" /> <excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" /> <excludeFolder url="file://$MODULE_DIR$/build/bundles" />
...@@ -65,16 +65,17 @@ ...@@ -65,16 +65,17 @@
<excludeFolder url="file://$MODULE_DIR$/build/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" /> <excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/res" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" /> <excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" /> <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content> </content>
<orderEntry type="jdk" jdkName="Android 4.3 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v4-18.0.0" level="project" /> <orderEntry type="library" exported="" name="HockeySDK-3.0.1" level="project" />
<orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices3159.aar" level="project" /> <orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices4030.aar" level="project" />
<orderEntry type="library" exported="" name="HockeySDK-3.0.0" level="project" />
<orderEntry type="library" exported="" name="native-libs" level="project" /> <orderEntry type="library" exported="" name="native-libs" level="project" />
<orderEntry type="library" exported="" name="ComActionbarsherlockActionbarsherlock440.aar" level="project" /> <orderEntry type="library" exported="" name="support-v4-19.0.0" level="project" />
<orderEntry type="library" exported="" name="ComAndroidSupportAppcompatV71900.aar" level="project" />
</component> </component>
</module> </module>
...@@ -3,7 +3,7 @@ buildscript { ...@@ -3,7 +3,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:0.5.+' classpath 'com.android.tools.build:gradle:0.7.+'
} }
} }
apply plugin: 'android' apply plugin: 'android'
...@@ -22,25 +22,49 @@ task nativeLibsToJar( ...@@ -22,25 +22,49 @@ task nativeLibsToJar(
into 'lib/' into 'lib/'
} }
tasks.withType(Compile) { tasks.withType(JavaCompile) {
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
tasks.withType(Compile) { tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar) compileTask -> compileTask.dependsOn(nativeLibsToJar)
} }
dependencies { dependencies {
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
compile 'com.google.android.gms:play-services:4.0.+' compile 'com.google.android.gms:play-services:4.0.+'
compile 'net.hockeyapp.android:HockeySDK:3.0.1' compile 'net.hockeyapp.android:HockeySDK:3.0.1'
compile 'com.android.support:support-v4:19.0.+' compile 'com.android.support:support-v4:19.0.+'
compile fileTree(dir: "$buildDir/native-libs", include: '*.jar') compile 'com.android.support:appcompat-v7:19.0.+'
compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
} }
android { android {
compileSdkVersion 19 compileSdkVersion 19
buildToolsVersion "19.0.0" buildToolsVersion '19.0.0'
signingConfigs {
debug {
storeFile file("debug.keystore")
}
release {
storeFile file("release.keystore")
}
}
buildTypes {
debug {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.debug
}
release {
debuggable false
jniDebugBuild false
signingConfig signingConfigs.release
}
}
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
......
NDK_TOOLCHAIN_VERSION := 4.8
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := tmessages LOCAL_MODULE := tmessages
LOCAL_CFLAGS = -w LOCAL_CFLAGS = -w -std=gnu99 -O3
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
./aes_core.c \ ./aes_core.c \
./aes_ige.c \ ./aes_ige.c \
...@@ -15,5 +16,6 @@ LOCAL_SRC_FILES := \ ...@@ -15,5 +16,6 @@ LOCAL_SRC_FILES := \
./org_telegram_SQLite_SQLiteDatabase.c \ ./org_telegram_SQLite_SQLiteDatabase.c \
./org_telegram_SQLite_SQLitePreparedStatement.c \ ./org_telegram_SQLite_SQLitePreparedStatement.c \
./org_telegram_SQLite.c ./org_telegram_SQLite.c
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
APP_PLATFORM := android-8 APP_PLATFORM := android-9
APP_ABI := armeabi armeabi-v7a x86 mips APP_ABI := armeabi armeabi-v7a x86
\ No newline at end of file \ No newline at end of file
#!/bin/bash
function build_one {
echo "Cleaning..."
make clean
echo "Configuring..."
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc" \
--arch=$ARCH \
--cc=$CC \
--cross-prefix=$CROSS_PREFIX \
--nm=$NM \
--sysroot=$PLATFORM \
--extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -fasm -Wno-psabi -fno-short-enums -Dipv6mr_interface=ipv6mr_ifindex -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
--disable-shared \
--enable-static \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl" \
\
--disable-everything \
--disable-network \
--enable-small \
--enable-zlib \
--disable-avfilter \
--disable-avdevice \
--disable-programs \
--disable-doc \
--disable-lsp \
--disable-dwt \
--disable-dct \
--enable-stripping \
--disable-postproc \
--disable-fft \
--disable-lzo \
--disable-rdft \
--disable-mdct \
--disable-debug \
\
--enable-muxer='mp4' \
--enable-protocol='file' \
--enable-encoder='aac,mpeg4' \
--enable-decoder='aac,amrnb,amrwb,flv,h263,h264' \
--enable-demuxer='flv,mpegvideo,mov' \
--enable-hwaccel='mpeg4_vaapi,mpeg4_vdpau' \
--enable-swresample \
--enable-swscale \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
echo "continue?"
read
make -j8 install
#$AR d libavcodec/libavcodec.a inverse.o
#$LD -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname libffmpeg.a -static -nostdlib -z noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a -lc -lm -lz -ldl --dynamic-linker=/system/bin/linker $GCCLIB
}
NDK=/Users/DrKLO/ndk9
#arm platform
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64
LD=$PREBUILT/bin/arm-linux-androideabi-ld
AR=$PREBUILT/bin/arm-linux-androideabi-ar
NM=$PREBUILT/bin/arm-linux-androideabi-nm
GCCLIB=$PREBUILT/lib/gcc/arm-linux-androideabi/4.8/libgcc.a
ARCH=arm
CC=$PREBUILT/bin/arm-linux-androideabi-gcc
CROSS_PREFIX=$PREBUILT/bin/arm-linux-androideabi-
#arm v6
CPU=armv6
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=/Users/DrKLO/ndk9/platforms/android-9/arch-$ARCH/usr
ADDITIONAL_CONFIGURE_FLAG=
build_one
#arm v7vfpv3
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
#PREFIX=./android/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#arm v7vfp
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
#PREFIX=./android/$CPU-vfp
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#arm v7n
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8"
#PREFIX=./android/$CPU
#ADDITIONAL_CONFIGURE_FLAG=--enable-neon
#build_one
#arm v6+vfp
#CPU=armv6
#OPTIMIZE_CFLAGS="-DCMP_HAVE_VFP -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU"
#PREFIX=./android/${CPU}_vfp
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#x86 platform
PLATFORM=$NDK/platforms/android-9/arch-x86
PREBUILT=$NDK/toolchains/x86-4.8/prebuilt/darwin-x86_64
LD=$PREBUILT/bin/i686-linux-android-ld
AR=$PREBUILT/bin/i686-linux-android-ar
NM=$PREBUILT/bin/i686-linux-android-nm
GCCLIB=$PREBUILT/lib/gcc/i686-linux-android/4.8/libgcc.a
ARCH=x86
CC=$PREBUILT/bin/i686-linux-android-gcc
CROSS_PREFIX=$PREBUILT/bin/i686-linux-android-
CPU=i686
OPTIMIZE_CFLAGS="-march=$CPU"
PREFIX=/Users/DrKLO/ndk9/platforms/android-9/arch-$ARCH/usr
ADDITIONAL_CONFIGURE_FLAG="--disable-mmx --disable-yasm"
build_one
...@@ -5,12 +5,7 @@ ...@@ -5,12 +5,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <android/log.h> #include <android/log.h>
#include "aes.h" #include "aes.h"
#include "log.h"
#define LOG_TAG "tmessages_native"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv) { JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv) {
unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL); unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL);
...@@ -84,100 +79,3 @@ JNIEXPORT jlong Java_org_telegram_messenger_Utilities_doPQNative(JNIEnv* env, jc ...@@ -84,100 +79,3 @@ JNIEXPORT jlong Java_org_telegram_messenger_Utilities_doPQNative(JNIEnv* env, jc
} }
return g; return g;
} }
//sqlite
/*JNIEXPORT void Java_org_telegram_messenger_Utilities_beginTransaction(JNIEnv* env, jobject object, int dbHandle) {
sqlite3 *db = (sqlite3 *)dbHandle;
if (db == NULL) {
return;
}
sqlite3_exec(db, "BEGIN", 0, 0, 0);
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_commitTransaction(JNIEnv* env, jobject object, int dbHandle) {
sqlite3 *db = (sqlite3 *)dbHandle;
if (db == NULL) {
return;
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
}
int Java_org_telegram_messenger_Utilities_step(JNIEnv* env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int errcode = 0 ;
errcode = sqlite3_step(handle);
if (errcode == SQLITE_ROW) {
return 0;
} else if(errcode == SQLITE_DONE) {
return 1;
} else if(errcode == SQLITE_BUSY) {
return -1;
}
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
int Java_org_telegram_messenger_Utilities_columnType(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
return sqlite3_column_type(handle, columnIndex);
}
int Java_org_telegram_messenger_Utilities_columnIsNull(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
return SQLITE_NULL == valType;
}
int Java_org_telegram_messenger_Utilities_columnIntValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int(handle, columnIndex);
}
jdouble Java_org_telegram_messenger_Utilities_columnDoubleValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_double(handle, columnIndex);
}
jstring Java_org_telegram_messenger_Utilities_columnStringValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
const char* str = sqlite3_column_text(handle, columnIndex);
if (str != 0) {
return (*env)->NewStringUTF(env, str);
}
return 0;
}
jbyteArray Java_org_telegram_messenger_Utilities_columnByteArrayValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
void *buf = sqlite3_column_blob(handle, columnIndex);
int length = sqlite3_column_bytes(handle, columnIndex);
if (buf != 0 && length > 0) {
jbyteArray result = (*env)->NewByteArray(env, length);
(*env)->SetByteArrayRegion(env, result, 0, length, buf);
return result;
}
return 0;
}*/
#ifndef log_h
#define log_h
#include <android/log.h>
#define LOG_TAG "tmessages_native"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#endif
...@@ -18,8 +18,15 @@ void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobj ...@@ -18,8 +18,15 @@ void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobj
sqlite3_exec(handle, "COMMIT", 0, 0, 0); sqlite3_exec(handle, "COMMIT", 0, 0, 0);
} }
int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName) { int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName, jstring tempDir) {
char const *fileNameStr = (*env)->GetStringUTFChars(env, fileName, 0); char const *fileNameStr = (*env)->GetStringUTFChars(env, fileName, 0);
char const *tempDirStr = (*env)->GetStringUTFChars(env, tempDir, 0);
if (sqlite3_temp_directory != 0) {
sqlite3_free(sqlite3_temp_directory);
}
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
sqlite3 *handle = 0; sqlite3 *handle = 0;
int err = sqlite3_open(fileNameStr, &handle); int err = sqlite3_open(fileNameStr, &handle);
if (SQLITE_OK != err) { if (SQLITE_OK != err) {
...@@ -28,5 +35,8 @@ int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, ...@@ -28,5 +35,8 @@ int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object,
if (fileNameStr != 0) { if (fileNameStr != 0) {
(*env)->ReleaseStringUTFChars(env, fileName, fileNameStr); (*env)->ReleaseStringUTFChars(env, fileName, fileNameStr);
} }
if (tempDirStr != 0) {
(*env)->ReleaseStringUTFChars(env, tempDir, tempDirStr);
}
return (int)handle; return (int)handle;
} }
This diff is collapsed.
This diff is collapsed.
...@@ -474,11 +474,14 @@ struct sqlite3_api_routines { ...@@ -474,11 +474,14 @@ struct sqlite3_api_routines {
** extension */ ** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else #else
/* This case when the file is being statically linked into the /* This case when the file is being statically linked into the
** application */ ** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/ # define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif #endif
#endif /* _SQLITE3EXT_H_ */ #endif /* _SQLITE3EXT_H_ */
#include <jni.h>
#include "video.h"
JNIEXPORT void Java_org_telegram_messenger_VideoTools_initialize(JNIEnv* env, jclass class) {
av_register_all();
}
JNIEXPORT void Java_org_telegram_messenger_VideoTools_convert(JNIEnv* env, jclass class, jstring in, jstring out, int bitr) {
char const *in_str = (*env)->GetStringUTFChars(env, in, 0);
char const *out_str = (*env)->GetStringUTFChars(env, out, 0);
convertFile(in_str, out_str, bitr);
if (in_str != 0) {
(*env)->ReleaseStringUTFChars(env, in, in_str);
}
if (out_str != 0) {
(*env)->ReleaseStringUTFChars(env, out, out_str);
}
}
#ifndef video_h
#define video_h
#include <libavformat/avformat.h>
int prepare_for_video_conversion(const char *dst_filename, AVCodecContext *video_dec_ctx, AVCodecContext *audio_dec_ctx, AVFormatContext *fmt_ctx, AVStream *src_video_stream, AVStream *src_audio_stream, int bitr);
int write_video_frame(AVFrame *src_frame);
int write_audio_frame(AVFrame *src_frame, AVCodecContext *src_codec);
void post_video_conversion();
void cleanup_out();
void onError();
void onProgress();
void onDone();
void convertFile(const char *src_filename, const char *dst_filename, int bitr);
#endif
#include "video.h"
#include <stdio.h>
#include <libavutil/timestamp.h>
#include <libavutil/imgutils.h>
#include "log.h"
AVPacket pkt;
int video_stream_idx = -1, audio_stream_idx = -1;
AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx = NULL;
AVFrame *frame = NULL;
AVStream *video_stream = NULL, *audio_stream = NULL;
AVFormatContext *fmt_ctx = NULL;
int64_t total_duration;
int64_t current_duration;
char *src = NULL;
char *dest = NULL;
int lastLog = 10;
void cleanup_in() {
if (video_dec_ctx) {
avcodec_close(video_dec_ctx);
video_dec_ctx = NULL;
}
if (audio_dec_ctx) {
avcodec_close(audio_dec_ctx);
audio_dec_ctx = NULL;
}
if (fmt_ctx) {
avformat_close_input(&fmt_ctx);
fmt_ctx = NULL;
}
if (frame) {
av_frame_free(&frame);
frame = NULL;
}
if (src) {
free(src);
src = NULL;
}
if (dest) {
free(dest);
dest = NULL;
}
total_duration = 0;
current_duration = 0;
video_stream_idx = -1;
audio_stream_idx = -1;
video_stream = NULL;
audio_stream = NULL;
lastLog = 10;
}
void onError() {
cleanup_in();
cleanup_out();
}
void onDone() {
LOGD("OK\n");
cleanup_in();
cleanup_out();
}
void onProgress() {
float progress = (float)current_duration / (float)total_duration * 100;
if (progress > lastLog) {
lastLog += 10;
LOGD("progress %.2f\n", progress);
}
}
int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type) {
int ret;
AVStream *st;
AVCodecContext *dec_ctx = NULL;
AVCodec *dec = NULL;
AVDictionary *opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0) {
LOGD("Could not find %s stream in input file\n", av_get_media_type_string(type));
return ret;
} else {
*stream_idx = ret;
st = fmt_ctx->streams[*stream_idx];
dec_ctx = st->codec;
dec = avcodec_find_decoder(dec_ctx->codec_id);
if (!dec) {
LOGD("Failed to find %s codec\n", av_get_media_type_string(type));
return ret;
}
av_dict_set(&opts, "refcounted_frames", "1", 0);
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
LOGD("Failed to open %s codec\n", av_get_media_type_string(type));
return ret;
}
}
return 0;
}
int decode_packet(int *got_frame, int cached) {
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx) {
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOGD("Error decoding video frame\n");
return ret;
}
if (*got_frame) {
ret = write_video_frame(frame);
if (ret < 0) {
return ret;
}
}
} else if (pkt.stream_index == audio_stream_idx) {
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOGD("Error decoding audio frame\n");
return ret;
}
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
ret = write_audio_frame(frame, audio_dec_ctx);
if (ret < 0) {
return -1;
}
}
frame->pts = AV_NOPTS_VALUE;
}
if (*got_frame) {
av_frame_unref(frame);
}
return decoded;
}
void convertFile(const char *src_filename, const char *dst_filename, int bitr) {
int ret = 0;
int got_frame;
src = malloc(strlen(src_filename) + 1);
memcpy(src, src_filename, strlen(src_filename));
src[strlen(src_filename)] = '\0';
dest = malloc(strlen(dst_filename) + 1);
memcpy(dest, dst_filename, strlen(dst_filename));
dest[strlen(dst_filename)] = '\0';
if ((ret = avformat_open_input(&fmt_ctx, src, NULL, NULL)) < 0) {
LOGD("Could not open source file %s, %s\n", src, av_err2str(ret));
onError();
return;
}
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
LOGD("Could not find stream information\n");
onError();
return;
}
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
video_stream = fmt_ctx->streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
}
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
audio_stream = fmt_ctx->streams[audio_stream_idx];
audio_dec_ctx = audio_stream->codec;
}
av_dump_format(fmt_ctx, 0, src, 0);
if (!audio_stream && !video_stream) {
LOGD("Could not find audio or video stream in the input, aborting\n");
onError();
return;
}
frame = av_frame_alloc();
if (!frame) {
LOGD("Could not allocate frame\n");
onError();
return;
}
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
if (video_stream) {
LOGD("Demuxing video from file '%s'\n", src);
}
if (audio_stream) {
LOGD("Demuxing audio from file '%s'\n", src);
}
ret = prepare_for_video_conversion(dest, video_dec_ctx, audio_dec_ctx, fmt_ctx, video_stream, audio_stream, bitr);
if (ret < 0) {
return;
}
if (video_stream) {
total_duration = video_stream->duration;
}
if (audio_stream) {
total_duration += audio_stream->duration;
}
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0) {
onError();
return;
}
pkt.data += ret;
pkt.size -= ret;
current_duration += pkt.duration;
onProgress();
} while (pkt.size > 0);
av_free_packet(&orig_pkt);
}
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
} while (got_frame);
post_video_conversion();
onDone();
}
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.telegram.messenger" package="org.telegram.messenger"
android:versionCode="98" android:versionCode="122"
android:versionName="1.2.7"> android:versionName="1.3.2">
<supports-screens android:anyDensity="true" <supports-screens android:anyDensity="true"
android:smallScreens="true" android:smallScreens="true"
android:normalScreens="true" android:normalScreens="true"
android:largeScreens="true" android:largeScreens="true"
android:resizeable="true" android:resizeable="true"
android:xlargeScreens="true"/> android:xlargeScreens="true"/>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-feature android:name="android.hardware.telephony" android:required="false" /> <uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false" /> <uses-feature android:name="android.hardware.wifi" android:required="false" />
<uses-feature android:name="android.hardware.LOCATION" android:required="false" /> <uses-feature android:name="android.hardware.LOCATION" android:required="false" />
<uses-feature android:name="android.hardware.screen.PORTRAIT" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
...@@ -48,24 +49,25 @@ ...@@ -48,24 +49,25 @@
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<permission android:name="org.telegram.messenger.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <permission android:name="org.telegram.messenger.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<permission android:name="org.telegram.messenger.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <permission android:name="org.telegram.messenger.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/AppName" android:label="@string/AppName"
android:theme="@style/Theme.Sherlock.Light" android:theme="@style/Theme.TMessages.Start"
android:name="org.telegram.ui.ApplicationLoader" android:name="org.telegram.ui.ApplicationLoader"
android:hardwareAccelerated="true"> android:hardwareAccelerated="true"
android:largeHeap="true">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your-google-maps-api-key-here" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your-google-maps-api-key-here" />
<activity <activity
android:name="org.telegram.ui.LaunchActivity" android:name="org.telegram.ui.LaunchActivity"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
...@@ -92,68 +94,78 @@ ...@@ -92,68 +94,78 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.LoginActivity" android:name="org.telegram.ui.LoginActivity"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity>
<activity
android:name="org.telegram.ui.CountrySelectActivity"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.TMessages"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.IntroActivity" android:name="org.telegram.ui.IntroActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.ApplicationActivity" android:name="org.telegram.ui.ApplicationActivity"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.TMessages" android:theme="@style/Theme.TMessages"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTask" android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.GalleryImageViewer" android:name="org.telegram.ui.GalleryImageViewer"
android:theme="@style/Theme.TMessages.Gallery" android:theme="@style/Theme.TMessages.Gallery"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity> </activity>
<activity android:name="net.hockeyapp.android.UpdateActivity" /> <activity android:name="net.hockeyapp.android.UpdateActivity" />
<receiver android:name="org.telegram.messenger.SmsListener"> <receiver android:name="org.telegram.messenger.SmsListener">
<intent-filter> <intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" /> <action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver <receiver
android:name="org.telegram.messenger.GcmBroadcastReceiver" android:name="org.telegram.messenger.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" > android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="org.telegram.messenger" /> <category android:name="org.telegram.messenger" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name="org.telegram.messenger.AuthenticatorService" <service android:name="org.telegram.messenger.AuthenticatorService"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/> <action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter> </intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" <meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/auth"/> android:resource="@xml/auth"/>
</service> </service>
<service android:name="org.telegram.messenger.ContactsSyncAdapterService" <service android:name="org.telegram.messenger.ContactsSyncAdapterService"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.content.SyncAdapter" /> <action android:name="android.content.SyncAdapter" />
</intent-filter> </intent-filter>
<meta-data android:name="android.content.SyncAdapter" <meta-data android:name="android.content.SyncAdapter"
android:resource="@xml/sync_contacts" /> android:resource="@xml/sync_contacts" />
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" <meta-data android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts" /> android:resource="@xml/contacts" />
</service> </service>
<uses-library android:name="com.google.android.maps" android:required="false"/> <uses-library android:name="com.google.android.maps" android:required="false"/>
</application> </application>
</manifest> </manifest>
6723;NF;Norfolk Island
5999;CW;Curaçao
1939;PR;Puerto Rico
1876;JM;Jamaica 1876;JM;Jamaica
1869;KN;Saint Kitts and Nevis 1869;KN;Saint Kitts & Nevis
1868;TT;Trinidad and Tobago 1868;TT;Trinidad & Tobago
1849;DO;Dominican Republic 1784;VC;Saint Vincent & the Grenadines
1829;DO;Dominican Republic
1809;DO;Dominican Republic
1787;PR;Puerto Rico
1784;VC;Saint Vincent and the Grenadines
1767;DM;Dominica 1767;DM;Dominica
1758;LC;Saint Lucia 1758;LC;Saint Lucia
1721;SX;Bonaire, Sint Eustatius and Saba 1721;SX;Sint Maarten
1684;AS;American Samoa 1684;AS;American Samoa
1671;GU;Guam 1671;GU;Guam
1670;MP;Northern Mariana Islands 1670;MP;Northern Mariana Islands
1664;MS;Montserrat 1664;MS;Montserrat
1649;TC;Turks and Caicos Islands 1649;TC;Turks & Caicos Islands
1473;GD;Grenada 1473;GD;Grenada
1441;BM;Bermuda 1441;BM;Bermuda
1345;KY;Cayman Islands 1345;KY;Cayman Islands
1340;VI;US Virgin Islands 1340;VI;US Virgin Islands
1284;VG;British Virgin Islands 1284;VG;British Virgin Islands
1268;AG;Antigua and Barbuda 1268;AG;Antigua & Barbuda
1264;AI;Anguilla 1264;AI;Anguilla
1246;BB;Barbados 1246;BB;Barbados
1242;BS;Bahamas 1242;BS;Bahamas
...@@ -45,7 +38,7 @@ ...@@ -45,7 +38,7 @@
966;SA;Saudi Arabia 966;SA;Saudi Arabia
965;KW;Kuwait 965;KW;Kuwait
964;IQ;Iraq 964;IQ;Iraq
963;SY;Syria 963;SY;Syrian Arab Republic
962;JO;Jordan 962;JO;Jordan
961;LB;Lebanon 961;LB;Lebanon
960;MV;Maldives 960;MV;Maldives
...@@ -66,7 +59,7 @@ ...@@ -66,7 +59,7 @@
685;WS;Samoa 685;WS;Samoa
683;NU;Niue 683;NU;Niue
682;CK;Cook Islands 682;CK;Cook Islands
681;WF;Wallis and Futuna 681;WF;Wallis & Futuna
680;PW;Palau 680;PW;Palau
679;FJ;Fiji 679;FJ;Fiji
678;VU;Vanuatu 678;VU;Vanuatu
...@@ -75,9 +68,10 @@ ...@@ -75,9 +68,10 @@
675;PG;Papua New Guinea 675;PG;Papua New Guinea
674;NR;Nauru 674;NR;Nauru
673;BN;Brunei Darussalam 673;BN;Brunei Darussalam
672;AU;Australia 672;NF;Norfolk Island
670;TL;East Timor 670;TL;Timor-Leste
599;BQ;Sint Maarten 599;BQ;Bonaire, Sint Eustatius & Saba
599;CW;Curaçao
598;UY;Uruguay 598;UY;Uruguay
597;SR;Suriname 597;SR;Suriname
596;MQ;Martinique 596;MQ;Martinique
...@@ -88,7 +82,7 @@ ...@@ -88,7 +82,7 @@
591;BO;Bolivia 591;BO;Bolivia
590;GP;Guadeloupe 590;GP;Guadeloupe
509;HT;Haiti 509;HT;Haiti
508;PM;Saint Pierre and Miquelon 508;PM;Saint Pierre & Miquelon
507;PA;Panama 507;PA;Panama
506;CR;Costa Rica 506;CR;Costa Rica
505;NI;Nicaragua 505;NI;Nicaragua
...@@ -101,7 +95,7 @@ ...@@ -101,7 +95,7 @@
421;SK;Slovakia 421;SK;Slovakia
420;CZ;Czech Republic 420;CZ;Czech Republic
389;MK;Macedonia 389;MK;Macedonia
387;BA;Bosnia and Herzegovina 387;BA;Bosnia & Herzegovina
386;SI;Slovenia 386;SI;Slovenia
385;HR;Croatia 385;HR;Croatia
382;ME;Montenegro 382;ME;Montenegro
...@@ -153,17 +147,17 @@ ...@@ -153,17 +147,17 @@
249;SD;Sudan 249;SD;Sudan
248;SC;Seychelles 248;SC;Seychelles
247;SH;Saint Helena 247;SH;Saint Helena
246;IO;United Kingdom 246;IO;Diego Garcia
245;GW;Guinea-Bissau 245;GW;Guinea-Bissau
244;AO;Angola 244;AO;Angola
243;CD;Congo, Democratic Republic 243;CD;Congo (Dem. Rep.)
242;CG;Congo 242;CG;Congo (Rep.)
241;GA;Gabon 241;GA;Gabon
240;GQ;Equatorial Guinea 240;GQ;Equatorial Guinea
239;ST;São Tomé and Príncipe 239;ST;São Tomé & Príncipe
238;CV;Cape Verde 238;CV;Cape Verde
237;CM;Cameroon 237;CM;Cameroon
236;CF;Central African Republic 236;CF;Central African Rep.
235;TD;Chad 235;TD;Chad
234;NG;Nigeria 234;NG;Nigeria
233;GH;Ghana 233;GH;Ghana
...@@ -228,8 +222,10 @@ ...@@ -228,8 +222,10 @@
31;NL;Netherlands 31;NL;Netherlands
30;GR;Greece 30;GR;Greece
27;ZA;South Africa 27;ZA;South Africa
20;EG;Egypt 20;EG;Egypt
7;KZ;Kazakhstan 7;KZ;Kazakhstan
7;RU;Russia 7;RU;Russian Federation
1;US;USA 1;PR;Puerto Rico
1;CA;Canada 1;DO;Dominican Rep.
\ No newline at end of file 1;CA;Canada
1;US;USA
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.traffic; package jawnae.pyronet;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
......
...@@ -31,14 +31,9 @@ import java.nio.channels.SocketChannel; ...@@ -31,14 +31,9 @@ import java.nio.channels.SocketChannel;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import jawnae.pyronet.events.PyroClientListener;
import jawnae.pyronet.traffic.ByteStream;
public class PyroClient { public class PyroClient {
private final PyroSelector selector; private final PyroSelector selector;
final PyroServer server;
private final SelectionKey key; private final SelectionKey key;
private final ByteStream outbound; private final ByteStream outbound;
...@@ -46,18 +41,17 @@ public class PyroClient { ...@@ -46,18 +41,17 @@ public class PyroClient {
// called by PyroSelector.connect() // called by PyroSelector.connect()
PyroClient(PyroSelector selector, InetSocketAddress bind, PyroClient(PyroSelector selector, InetSocketAddress bind,
InetSocketAddress host) throws IOException { InetSocketAddress host) throws IOException {
this(selector, null, PyroClient.bindAndConfigure(selector, this(selector, PyroClient.bindAndConfigure(selector,
SocketChannel.open(), bind)); SocketChannel.open(), bind));
((SocketChannel) this.key.channel()).connect(host); ((SocketChannel) this.key.channel()).connect(host);
} }
// called by PyroClient and PyroServer // called by PyroClient and PyroServer
PyroClient(PyroSelector selector, PyroServer server, SelectionKey key) { PyroClient(PyroSelector selector, SelectionKey key) {
this.selector = selector; this.selector = selector;
this.selector.checkThread(); this.selector.checkThread();
this.server = server;
this.key = key; this.key = key;
this.key.attach(this); this.key.attach(this);
...@@ -163,20 +157,6 @@ public class PyroClient { ...@@ -163,20 +157,6 @@ public class PyroClient {
// //
/**
* Returns the server that accepted this client.
*
* @throws PyroException
* if this client was not accepted by a server (it connected to
* a server)
*/
public final PyroServer getServer() throws PyroException {
if (this.server == null)
throw new PyroException("this client was not accepted by a server");
return this.server;
}
// //
// //
...@@ -425,7 +405,7 @@ public class PyroClient { ...@@ -425,7 +405,7 @@ public class PyroClient {
private int onReadyToWrite(long now) throws IOException { private int onReadyToWrite(long now) throws IOException {
this.selector.checkThread(); this.selector.checkThread();
this.lastEventTime = now; //this.lastEventTime = now;
int sent = 0; int sent = 0;
...@@ -479,13 +459,9 @@ public class PyroClient { ...@@ -479,13 +459,9 @@ public class PyroClient {
return; return;
} }
if (this.server != null) {
this.server.onDisconnect(this);
}
if (cause instanceof ConnectException) { if (cause instanceof ConnectException) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.unconnectableClient(this); listener.unconnectableClient(this, (Exception)cause);
} else if (cause instanceof EOFException) // after read=-1 } else if (cause instanceof EOFException) // after read=-1
{ {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
...@@ -495,7 +471,7 @@ public class PyroClient { ...@@ -495,7 +471,7 @@ public class PyroClient {
listener.droppedClient(this, (IOException) cause); listener.droppedClient(this, (IOException) cause);
} else if (!(cause instanceof String)) { } else if (!(cause instanceof String)) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.unconnectableClient(this); listener.unconnectableClient(this, null);
} else if (cause.equals("local")) { } else if (cause.equals("local")) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.disconnectedClient(this); listener.disconnectedClient(this);
...@@ -551,7 +527,7 @@ public class PyroClient { ...@@ -551,7 +527,7 @@ public class PyroClient {
// channel.socket().setSoLinger(false, 0); // this will b0rk your // channel.socket().setSoLinger(false, 0); // this will b0rk your
// connections // connections
channel.socket().setSoLinger(true, 4); channel.socket().setSoLinger(true, 4);
channel.socket().setReuseAddress(true); channel.socket().setReuseAddress(false);
channel.socket().setKeepAlive(false); channel.socket().setKeepAlive(false);
channel.socket().setTcpNoDelay(true); channel.socket().setTcpNoDelay(true);
channel.socket().setReceiveBufferSize(PyroSelector.BUFFER_SIZE); channel.socket().setReceiveBufferSize(PyroSelector.BUFFER_SIZE);
......
...@@ -16,19 +16,17 @@ ...@@ -16,19 +16,17 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.events; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public class PyroClientAdapter implements PyroClientListener { public class PyroClientAdapter implements PyroClientListener {
public void connectedClient(PyroClient client) { public void connectedClient(PyroClient client) {
// //
} }
public void unconnectableClient(PyroClient client) { public void unconnectableClient(PyroClient client, Exception cause) {
System.out.println("unconnectable"); System.out.println("unconnectable");
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.events; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -26,7 +26,7 @@ import jawnae.pyronet.PyroClient; ...@@ -26,7 +26,7 @@ import jawnae.pyronet.PyroClient;
public interface PyroClientListener { public interface PyroClientListener {
public void connectedClient(PyroClient client); public void connectedClient(PyroClient client);
public void unconnectableClient(PyroClient client); public void unconnectableClient(PyroClient client, Exception cause);
public void droppedClient(PyroClient client, IOException cause); public void droppedClient(PyroClient client, IOException cause);
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
package jawnae.pyronet; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -27,14 +26,11 @@ import java.nio.channels.CancelledKeyException; ...@@ -27,14 +26,11 @@ import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectableChannel; import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import jawnae.pyronet.events.PyroSelectorListener;
public class PyroSelector { public class PyroSelector {
public static boolean DO_NOT_CHECK_NETWORK_THREAD = true; public static boolean DO_NOT_CHECK_NETWORK_THREAD = true;
...@@ -46,14 +42,7 @@ public class PyroSelector { ...@@ -46,14 +42,7 @@ public class PyroSelector {
final ByteBuffer networkBuffer; final ByteBuffer networkBuffer;
final PyroSelectorListener listener;
public PyroSelector() { public PyroSelector() {
this(null);
}
public PyroSelector(PyroSelectorListener listener) {
this.listener = listener;
this.networkBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE); this.networkBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
try { try {
...@@ -111,28 +100,6 @@ public class PyroSelector { ...@@ -111,28 +100,6 @@ public class PyroSelector {
} }
} }
public PyroServer listen(InetSocketAddress end, int backlog)
throws IOException {
try {
return new PyroServer(this, nioSelector, end, backlog);
} catch (IOException exc) {
if (this.listener == null)
throw exc;
this.listener.serverBindFailed(exc);
return null;
}
}
public PyroServer listen(InetSocketAddress end) throws IOException {
return this.listen(end, 50);
}
public PyroServer listen(int port) throws IOException {
return this.listen(new InetSocketAddress(InetAddress.getLocalHost(),
port));
}
public PyroClient connect(InetSocketAddress host) throws IOException { public PyroClient connect(InetSocketAddress host) throws IOException {
return this.connect(host, null); return this.connect(host, null);
} }
...@@ -142,11 +109,7 @@ public class PyroSelector { ...@@ -142,11 +109,7 @@ public class PyroSelector {
try { try {
return new PyroClient(this, bind, host); return new PyroClient(this, bind, host);
} catch (IOException exc) { } catch (IOException exc) {
if (this.listener == null) throw exc;
throw exc;
this.listener.clientBindFailed(exc);
return null;
} }
} }
...@@ -173,16 +136,10 @@ public class PyroSelector { ...@@ -173,16 +136,10 @@ public class PyroSelector {
if (task == null) if (task == null)
break; break;
if (this.listener != null)
this.listener.executingTask(task);
try { try {
task.run(); task.run();
} catch (Throwable cause) { } catch (Throwable cause) {
if (this.listener != null) cause.printStackTrace();
this.listener.taskCrashed(task, cause);
else
cause.printStackTrace();
} }
} }
} }
...@@ -192,15 +149,9 @@ public class PyroSelector { ...@@ -192,15 +149,9 @@ public class PyroSelector {
try { try {
selected = nioSelector.select(timeout); selected = nioSelector.select(timeout);
} catch (IOException exc) { } catch (IOException exc) {
if (this.listener != null) exc.printStackTrace();
this.listener.selectFailure(exc);
else
exc.printStackTrace();
return; return;
} }
if (this.listener != null)
this.listener.selectedKeys(selected);
} }
private final void handleSelectedKeys(long now) { private final void handleSelectedKeys(long now) {
...@@ -210,17 +161,8 @@ public class PyroSelector { ...@@ -210,17 +161,8 @@ public class PyroSelector {
SelectionKey key = keys.next(); SelectionKey key = keys.next();
keys.remove(); keys.remove();
if (key.channel() instanceof ServerSocketChannel) {
PyroServer server = (PyroServer) key.attachment();
if (this.listener != null)
this.listener.serverSelected(server);
server.onInterestOp();
}
if (key.channel() instanceof SocketChannel) { if (key.channel() instanceof SocketChannel) {
PyroClient client = (PyroClient) key.attachment(); PyroClient client = (PyroClient) key.attachment();
if (this.listener != null)
this.listener.clientSelected(client, key.readyOps());
client.onInterestOp(now); client.onInterestOp(now);
} }
} }
......
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import jawnae.pyronet.addon.PyroSelectorProvider;
import jawnae.pyronet.events.PyroServerListener;
public class PyroServer implements Iterable<PyroClient> {
private final PyroSelector selector;
public final SelectionKey serverKey;
final List<PyroClient> clients;
PyroServer(PyroSelector selector, Selector nioSelector,
InetSocketAddress endpoint, int backlog) throws IOException {
this.selector = selector;
this.selector.checkThread();
ServerSocketChannel ssc;
ssc = ServerSocketChannel.open();
ssc.socket().bind(endpoint, backlog);
ssc.configureBlocking(false);
this.serverKey = ssc.register(nioSelector, SelectionKey.OP_ACCEPT);
this.serverKey.attach(this);
this.clients = new ArrayList<PyroClient>();
this.listeners = new CopyOnWriteArrayList<PyroServerListener>();
}
//
private final List<PyroServerListener> listeners;
public void addListener(PyroServerListener listener) {
this.selector.checkThread();
this.listeners.add(listener);
}
public void removeListener(PyroServerListener listener) {
this.selector.checkThread();
this.listeners.remove(listener);
}
public void removeListeners() {
this.selector.checkThread();
this.listeners.clear();
}
/**
* Returns the network that created this server
*/
public PyroSelector selector() {
return this.selector;
}
private PyroSelectorProvider selectorProvider;
/**
* By installing a PyroSelectorProvider you alter the PyroSelector used to
* do the I/O of a PyroClient. This can be used for multi-threading your
* network code
*/
public void installSelectorProvider(PyroSelectorProvider selectorProvider) {
this.selector().checkThread();
this.selectorProvider = selectorProvider;
}
void onInterestOp() {
if (!serverKey.isValid())
throw new PyroException("invalid selection key");
try {
if (serverKey.isAcceptable()) {
this.onReadyToAccept();
}
} catch (IOException exc) {
throw new IllegalStateException(exc);
}
}
/**
* Returns an iterator to access all connected clients of this server
*/
@Override
public Iterator<PyroClient> iterator() {
this.selector.checkThread();
List<PyroClient> copy = new ArrayList<PyroClient>();
copy.addAll(this.clients);
return copy.iterator();
}
/**
* Closes the server socket. Any current connections will continue.
*/
public void close() throws IOException {
this.selector.checkThread();
this.serverKey.channel().close();
}
/**
* Closes the server socket. Any current connections will be closed.
*/
public void terminate() throws IOException {
this.close();
for (PyroClient client: this) {
client.dropConnection();
}
}
private void onReadyToAccept() throws IOException {
this.selector.checkThread();
final SocketChannel channel = ((ServerSocketChannel) serverKey
.channel()).accept();
final PyroSelector acceptedClientSelector;
{
if (this.selectorProvider == null)
acceptedClientSelector = this.selector;
else
acceptedClientSelector = this.selectorProvider
.provideFor(channel);
}
if (acceptedClientSelector == this.selector) {
SelectionKey clientKey = PyroClient.configure(
acceptedClientSelector, channel, false);
PyroClient client = new PyroClient(acceptedClientSelector, this,
clientKey);
this.fireAcceptedClient(client);
this.clients.add(client);
} else {
// create client in PyroClient-selector thread
acceptedClientSelector.scheduleTask(new Runnable() {
@Override
public void run() {
SelectionKey clientKey;
try {
clientKey = PyroClient.configure(
acceptedClientSelector, channel, false);
} catch (IOException exc) {
throw new IllegalStateException(exc);
}
final PyroClient client = new PyroClient(
acceptedClientSelector, PyroServer.this, clientKey);
PyroServer.this.fireAcceptedClient(client);
// add client to list in PyroServer-selector thread
PyroServer.this.selector().scheduleTask(new Runnable() {
@Override
public void run() {
PyroServer.this.clients.add(client);
}
});
PyroServer.this.selector().wakeup();
}
});
acceptedClientSelector.wakeup();
}
}
void fireAcceptedClient(PyroClient client) {
for (PyroServerListener listener: this.listeners) {
listener.acceptedClient(client);
}
}
void onDisconnect(final PyroClient client) {
if (this.selector().isNetworkThread()) {
this.clients.remove(client);
} else {
// we are in the PyroClient-selector thread
this.selector().scheduleTask(new Runnable() {
@Override
public void run() {
// call again from the PyroServer-selector thread
PyroServer.this.onDisconnect(client);
}
});
this.selector().wakeup();
}
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import jawnae.pyronet.PyroSelector;
public class PyroRoundrobinSelectorProvider implements PyroSelectorProvider {
private final PyroSelector[] selectors;
private int index;
public PyroRoundrobinSelectorProvider(PyroSelector[] selectors) {
this.selectors = Arrays.copyOf(selectors, selectors.length);
}
@Override
public PyroSelector provideFor(SocketChannel channel) {
// this is called from the PyroServer-selector thread
return this.selectors[this.index++ % this.selectors.length];
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import jawnae.pyronet.PyroSelector;
public interface PyroSelectorProvider {
public PyroSelector provideFor(SocketChannel channel);
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import jawnae.pyronet.PyroSelector;
public class PyroSingletonSelectorProvider implements PyroSelectorProvider {
private final PyroSelector selector;
public PyroSingletonSelectorProvider(PyroSelector selector) {
this.selector = selector;
}
@Override
public PyroSelector provideFor(SocketChannel channel) {
return this.selector;
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public class PyroLazyBastardAdapter implements PyroSelectorListener,
PyroServerListener, PyroClientListener {
// --------------- PyroSelectorListener
public void executingTask(Runnable task) {
//
}
public void taskCrashed(Runnable task, Throwable cause) {
System.out.println(this.getClass().getSimpleName()
+ ".taskCrashed() caught exception:");
cause.printStackTrace();
}
public void selectedKeys(int count) {
//
}
public void selectFailure(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".selectFailure() caught exception:");
cause.printStackTrace();
}
public void serverSelected(PyroServer server) {
//
}
public void clientSelected(PyroClient client, int readyOps) {
//
}
// ------------- PyroServerListener
public void acceptedClient(PyroClient client) {
//
}
// ------------- PyroClientListener
public void connectedClient(PyroClient client) {
//
}
public void unconnectableClient(PyroClient client) {
System.out.println(this.getClass().getSimpleName()
+ ".unconnectableClient()");
}
public void droppedClient(PyroClient client, IOException cause) {
if (cause != null && !(cause instanceof EOFException)) {
System.out.println(this.getClass().getSimpleName()
+ ".droppedClient() caught exception: " + cause);
}
}
public void disconnectedClient(PyroClient client) {
//
}
//
public void receivedData(PyroClient client, ByteBuffer data) {
//
}
public void sentData(PyroClient client, int bytes) {
//
}
@Override
public void serverBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception:");
cause.printStackTrace();
}
@Override
public void clientBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception:");
cause.printStackTrace();
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.IOException;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public class PyroSelectorAdapter implements PyroSelectorListener {
public void executingTask(Runnable task) {
//
}
public void taskCrashed(Runnable task, Throwable cause) {
System.out.println(this.getClass().getSimpleName()
+ " caught exception: " + cause);
}
//
public void selectedKeys(int count) {
//
}
public void selectFailure(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ " caught exception: " + cause);
}
//
public void serverSelected(PyroServer server) {
//
}
public void clientSelected(PyroClient client, int readyOps) {
//
}
//
@Override
public void serverBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception: " + cause);
}
@Override
public void clientBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception: " + cause);
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.IOException;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public interface PyroSelectorListener {
public void executingTask(Runnable task);
public void taskCrashed(Runnable task, Throwable cause);
//
public void selectedKeys(int count);
public void selectFailure(IOException cause);
//
public void serverSelected(PyroServer server);
public void clientSelected(PyroClient client, int readyOps);
//
public void serverBindFailed(IOException cause);
public void clientBindFailed(IOException cause);
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import jawnae.pyronet.PyroClient;
public class PyroServerAdapter implements PyroServerListener {
@Override
public void acceptedClient(PyroClient client) {
//
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import jawnae.pyronet.PyroClient;
public interface PyroServerListener {
/**
* Note: invoked from the PyroSelector-thread that created this PyroClient
*/
public void acceptedClient(PyroClient client);
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public interface ByteSink {
public static int FEED_ACCEPTED = 1;
public static int FEED_ACCEPTED_LAST = 2;
public static int FEED_REJECTED = 3;
/**
* determines what to do with the specified byte: accept, accept as final
* byte, reject
*/
public int feed(byte b);
/**
* Resets the state of this ByteSink, allowing it to be enqueued again
*/
public void reset();
/**
* Called by the client when this ByteSink is complete
*/
public void onReady(ByteBuffer buffer);
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public abstract class ByteSinkEndsWith implements ByteSink {
private final ByteBuffer result;
private final byte[] endsWith;
private final boolean includeEndsWith;
private int matchCount;
private int filled;
public ByteSinkEndsWith(byte[] endsWith, int capacity,
boolean includeEndsWith) {
if (endsWith == null || endsWith.length == 0)
throw new IllegalStateException();
this.result = ByteBuffer.allocate(capacity);
this.endsWith = endsWith;
this.includeEndsWith = includeEndsWith;
this.reset();
}
@Override
public void reset() {
this.result.clear();
this.matchCount = 0;
this.filled = 0;
}
@Override
public int feed(byte b) {
if (this.endsWith[this.matchCount] == b) {
this.matchCount++;
} else {
this.matchCount = 0;
}
this.result.put(this.filled, b);
this.filled += 1;
if (this.matchCount == this.endsWith.length) {
int len = this.filled
- (this.includeEndsWith ? 0 : this.endsWith.length);
this.result.limit(len);
this.onReady(this.result);
return FEED_ACCEPTED_LAST;
}
return ByteSink.FEED_ACCEPTED;
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public abstract class ByteSinkLength implements ByteSink {
private final ByteBuffer result;
private int filled;
public ByteSinkLength(int size) {
if (size == 0)
throw new IllegalArgumentException();
this.result = ByteBuffer.allocate(size);
this.reset();
}
@Override
public void reset() {
this.result.clear();
this.filled = 0;
}
@Override
public int feed(byte b) {
this.result.put(this.filled, b);
this.filled += 1;
if (this.filled == this.result.capacity()) {
this.onReady(this.result);
return FEED_ACCEPTED_LAST;
}
return ByteSink.FEED_ACCEPTED;
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket16 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
if (payload.length > 0x0000FFFF) {
throw new IllegalStateException("packet bigger than 64K-1 bytes");
}
byte[] wrapped = new byte[2 + payload.length];
wrapped[0] = (byte) (payload.length >> 8);
wrapped[1] = (byte) (payload.length >> 0);
System.arraycopy(payload, 0, wrapped, 2, payload.length);
client.write(client.selector().malloc(wrapped));
}
//
ByteSinkLength current;
public ByteSinkPacket16() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(2) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = buffer.getShort(0) & 0xFFFF;
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket16.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket16.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
}
else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket24 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
if (payload.length > 0x00FFFFFF) {
throw new IllegalStateException("packet bigger than 16M-1 bytes");
}
byte[] wrapped = new byte[3 + payload.length];
wrapped[0] = (byte) (payload.length >> 16);
wrapped[1] = (byte) (payload.length >> 8);
wrapped[2] = (byte) (payload.length >> 0);
System.arraycopy(payload, 0, wrapped, 3, payload.length);
client.write(client.selector().malloc(wrapped));
}
//
ByteSinkLength current;
public ByteSinkPacket24() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(3) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = ((buffer.getShort(0) & 0xFFFF) << 8)
| (buffer.get(3) & 0xFF);
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket24.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket24.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
} else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket32 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
boolean isExtreme = (payload.length > 0xFFFFFFFF - 4);
byte[] wrapped = new byte[4 + (isExtreme ? 0 : payload.length)];
wrapped[0] = (byte) (payload.length >> 24);
wrapped[1] = (byte) (payload.length >> 16);
wrapped[2] = (byte) (payload.length >> 8);
wrapped[3] = (byte) (payload.length >> 0);
if (!isExtreme) {
System.arraycopy(payload, 0, wrapped, 4, payload.length);
}
client.write(client.selector().malloc(wrapped));
if (isExtreme) {
client.write(client.selector().malloc(payload));
}
}
//
ByteSinkLength current;
public ByteSinkPacket32() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(4) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = buffer.getInt(0);
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket24.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket32.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
}
else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroSelector;
import jawnae.pyronet.events.PyroClientAdapter;
public class PyroByteSinkFeeder extends PyroClientAdapter {
private final PyroSelector selector;
private final ByteStream inbound;
private final LinkedList<ByteSink> sinks;
public PyroByteSinkFeeder(PyroClient client) {
this(client.selector());
}
public PyroByteSinkFeeder(PyroSelector selector) {
this(selector, 8 * 1024);
}
public PyroByteSinkFeeder(PyroSelector selector, int bufferSize) {
this.selector = selector;
this.inbound = new ByteStream();
this.sinks = new LinkedList<ByteSink>();
}
//
@Override
public void receivedData(PyroClient client, ByteBuffer data) {
this.feed(data);
}
//
public ByteBuffer shutdown() {
int bytes = this.inbound.getByteCount();
ByteBuffer tmp = this.selector.malloc(bytes);
this.inbound.get(tmp);
this.inbound.discard(bytes);
tmp.flip();
return tmp;
}
public void addByteSink(ByteSink sink) {
this.selector.checkThread();
this.register(sink);
}
public void feed(ByteBuffer data) {
ByteBuffer copy = this.selector.copy(data);
this.inbound.append(copy);
this.fill();
}
final void register(ByteSink sink) {
this.sinks.addLast(sink);
this.fill();
}
private final void fill() {
if (this.sinks.isEmpty()) {
return;
}
ByteSink currentSink = this.sinks.removeFirst();
while (currentSink != null && inbound.hasData()) {
switch (currentSink.feed(inbound.read())) {
case ByteSink.FEED_ACCEPTED:
continue; // continue to next feed
case ByteSink.FEED_ACCEPTED_LAST:
break; // break out switch, not while
case ByteSink.FEED_REJECTED:
break; // break out switch, not while
}
if (this.sinks.isEmpty()) {
currentSink = null;
break;
}
currentSink = this.sinks.removeFirst();
}
if (currentSink != null) {
this.sinks.addFirst(currentSink);
}
}
}
...@@ -36,6 +36,7 @@ import java.util.Locale; ...@@ -36,6 +36,7 @@ import java.util.Locale;
public class PhoneFormat { public class PhoneFormat {
public byte[] data; public byte[] data;
private boolean initialzed = false;
public ByteBuffer buffer; public ByteBuffer buffer;
public String defaultCountry; public String defaultCountry;
public String defaultCallingCode; public String defaultCallingCode;
...@@ -90,6 +91,7 @@ public class PhoneFormat { ...@@ -90,6 +91,7 @@ public class PhoneFormat {
buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.order(ByteOrder.LITTLE_ENDIAN);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return;
} }
if (countryCode != null && countryCode.length() != 0) { if (countryCode != null && countryCode.length() != 0) {
...@@ -104,6 +106,7 @@ public class PhoneFormat { ...@@ -104,6 +106,7 @@ public class PhoneFormat {
countryCallingCode = new HashMap<String, String>(255); countryCallingCode = new HashMap<String, String>(255);
parseDataHeader(); parseDataHeader();
initialzed = true;
} }
public String defaultCallingCode() { public String defaultCallingCode() {
...@@ -139,6 +142,9 @@ public class PhoneFormat { ...@@ -139,6 +142,9 @@ public class PhoneFormat {
} }
public String format(String orig) { public String format(String orig) {
if (!initialzed) {
return orig;
}
String str = strip(orig); String str = strip(orig);
if (str.startsWith("+")) { if (str.startsWith("+")) {
...@@ -177,6 +183,9 @@ public class PhoneFormat { ...@@ -177,6 +183,9 @@ public class PhoneFormat {
} }
public boolean isPhoneNumberValid(String phoneNumber) { public boolean isPhoneNumberValid(String phoneNumber) {
if (!initialzed) {
return true;
}
String str = strip(phoneNumber); String str = strip(phoneNumber);
if (str.startsWith("+")) { if (str.startsWith("+")) {
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import android.util.Log; import org.telegram.messenger.FileLog;
public class SQLiteCursor { public class SQLiteCursor {
...@@ -83,14 +83,14 @@ public class SQLiteCursor { ...@@ -83,14 +83,14 @@ public class SQLiteCursor {
int repeatCount = 6; int repeatCount = 6;
while (repeatCount-- != 0) { while (repeatCount-- != 0) {
try { try {
Log.e("tmessages", "sqlite busy, waiting..."); FileLog.e("tmessages", "sqlite busy, waiting...");
Thread.sleep(500); Thread.sleep(500);
res = preparedStatement.step(); res = preparedStatement.step();
if (res == 0) { if (res == 0) {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
if (res == -1) { if (res == -1) {
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import org.telegram.messenger.FileLog;
import org.telegram.ui.ApplicationLoader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import android.util.Log;
public class SQLiteDatabase { public class SQLiteDatabase {
private final int sqliteHandle; private final int sqliteHandle;
...@@ -25,7 +26,7 @@ public class SQLiteDatabase { ...@@ -25,7 +26,7 @@ public class SQLiteDatabase {
} }
public SQLiteDatabase(String fileName) throws SQLiteException { public SQLiteDatabase(String fileName) throws SQLiteException {
sqliteHandle = opendb(fileName); sqliteHandle = opendb(fileName, ApplicationLoader.applicationContext.getFilesDir().getPath());
isOpen = true; isOpen = true;
preparedMap = new HashMap<String, SQLitePreparedStatement>(); preparedMap = new HashMap<String, SQLitePreparedStatement>();
} }
...@@ -111,7 +112,7 @@ public class SQLiteDatabase { ...@@ -111,7 +112,7 @@ public class SQLiteDatabase {
} }
closedb(sqliteHandle); closedb(sqliteHandle);
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("tmessages", e.getMessage(), e); FileLog.e("tmessages", e.getMessage(), e);
} }
isOpen = false; isOpen = false;
} }
...@@ -142,7 +143,7 @@ public class SQLiteDatabase { ...@@ -142,7 +143,7 @@ public class SQLiteDatabase {
commitTransaction(sqliteHandle); commitTransaction(sqliteHandle);
} }
native int opendb(String fileName) throws SQLiteException; native int opendb(String fileName, String tempDir) throws SQLiteException;
native void closedb(int sqliteHandle) throws SQLiteException; native void closedb(int sqliteHandle) throws SQLiteException;
native void beginTransaction(int sqliteHandle); native void beginTransaction(int sqliteHandle);
native void commitTransaction(int sqliteHandle); native void commitTransaction(int sqliteHandle);
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import android.util.Log; import org.telegram.messenger.FileLog;
public class SQLitePreparedStatement { public class SQLitePreparedStatement {
private boolean isFinalized = false; private boolean isFinalized = false;
...@@ -90,7 +90,7 @@ public class SQLitePreparedStatement { ...@@ -90,7 +90,7 @@ public class SQLitePreparedStatement {
isFinalized = true; isFinalized = true;
finalize(sqliteStatementHandle); finalize(sqliteStatementHandle);
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("tmessages", e.getMessage(), e); FileLog.e("tmessages", e.getMessage(), e);
} }
} }
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -8,9 +8,7 @@ ...@@ -8,9 +8,7 @@
package org.telegram.TL; package org.telegram.TL;
import android.util.Log; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.SerializedData; import org.telegram.messenger.SerializedData;
import java.util.HashMap; import java.util.HashMap;
...@@ -373,6 +371,10 @@ public class TLClassStore { ...@@ -373,6 +371,10 @@ public class TLClassStore {
classStore.put(TLRPC.TL_messages_sendEncryptedFile.constructor, TLRPC.TL_messages_sendEncryptedFile.class); classStore.put(TLRPC.TL_messages_sendEncryptedFile.constructor, TLRPC.TL_messages_sendEncryptedFile.class);
classStore.put(TLRPC.TL_messages_sendEncryptedService.constructor, TLRPC.TL_messages_sendEncryptedService.class); classStore.put(TLRPC.TL_messages_sendEncryptedService.constructor, TLRPC.TL_messages_sendEncryptedService.class);
classStore.put(TLRPC.TL_messages_receivedQueue.constructor, TLRPC.TL_messages_receivedQueue.class); classStore.put(TLRPC.TL_messages_receivedQueue.constructor, TLRPC.TL_messages_receivedQueue.class);
classStore.put(TLRPC.TL_upload_saveBigFilePart.constructor, TLRPC.TL_upload_saveBigFilePart.class);
classStore.put(TLRPC.TL_inputEncryptedFileBigUploaded.constructor, TLRPC.TL_inputEncryptedFileBigUploaded.class);
classStore.put(TLRPC.TL_inputFileBig.constructor, TLRPC.TL_inputFileBig.class);
classStore.put(TLRPC.TL_messageMediaUnsupported.constructor, TLRPC.TL_messageMediaUnsupported.class);
classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class); classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class);
classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class); classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class);
...@@ -381,6 +383,9 @@ public class TLClassStore { ...@@ -381,6 +383,9 @@ public class TLClassStore {
classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class); classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class);
classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class); classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class);
classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class); classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class);
classStore.put(TLRPC.TL_messageActionUserUpdatedPhoto.constructor, TLRPC.TL_messageActionUserUpdatedPhoto.class);
classStore.put(TLRPC.TL_messageActionUserJoined.constructor, TLRPC.TL_messageActionUserJoined.class);
classStore.put(TLRPC.TL_messageActionLoginUnknownLocation.constructor, TLRPC.TL_messageActionLoginUnknownLocation.class);
} }
static TLClassStore store = null; static TLClassStore store = null;
...@@ -419,16 +424,14 @@ public class TLClassStore { ...@@ -419,16 +424,14 @@ public class TLClassStore {
} }
return response; return response;
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
Log.e("tmessages", "can't create class"); FileLog.e("tmessages", "can't create class");
return null; return null;
} catch (InstantiationException e2) { } catch (InstantiationException e2) {
Log.e("tmessages", "can't create class"); FileLog.e("tmessages", "can't create class");
return null; return null;
} }
} else { } else {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.e("tmessages", String.format("unknown class %x", constructor));
Log.e("tmessages", String.format("unknown class %x", constructor));
}
return null; return null;
//throw new RuntimeException(String.format("unknown class %x", constructor)); //throw new RuntimeException(String.format("unknown class %x", constructor));
} }
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -13,13 +13,11 @@ import android.accounts.OperationCanceledException; ...@@ -13,13 +13,11 @@ import android.accounts.OperationCanceledException;
import android.app.Service; import android.app.Service;
import android.content.AbstractThreadedSyncAdapter; import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient; import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SyncResult; import android.content.SyncResult;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log;
public class ContactsSyncAdapterService extends Service { public class ContactsSyncAdapterService extends Service {
private static SyncAdapterImpl sSyncAdapter = null; private static SyncAdapterImpl sSyncAdapter = null;
...@@ -41,7 +39,7 @@ public class ContactsSyncAdapterService extends Service { ...@@ -41,7 +39,7 @@ public class ContactsSyncAdapterService extends Service {
try { try {
ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult); ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
} catch (OperationCanceledException e) { } catch (OperationCanceledException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
} }
...@@ -60,6 +58,6 @@ public class ContactsSyncAdapterService extends Service { ...@@ -60,6 +58,6 @@ public class ContactsSyncAdapterService extends Service {
private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
throws OperationCanceledException { throws OperationCanceledException {
Log.i("telegram", "performSync: " + account.toString()); FileLog.d("telegram", "performSync: " + account.toString());
} }
} }
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -8,24 +8,32 @@ ...@@ -8,24 +8,32 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.util.Log; import android.content.Context;
import android.content.SharedPreferences;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.ui.ApplicationLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
public class Datacenter { public class Datacenter {
private final int DATA_VERSION = 2;
public int datacenterId; public int datacenterId;
public String address; public ArrayList<String> addresses = new ArrayList<String>();
public int port; public HashMap<String, Integer> ports = new HashMap<String, Integer>();
public int[] defaultPorts = new int[] {-1, 80, -1, 88, -1, 443, -1, 80, -1, 443, -1};
public boolean authorized; public boolean authorized;
public long authSessionId; public long authSessionId;
public long authDownloadSessionId; public long authDownloadSessionId;
public long authUploadSessionId; public long authUploadSessionId;
public byte[] authKey; public byte[] authKey;
public byte[] authKeyId; public byte[] authKeyId;
private volatile int currentPortNum = 0;
private volatile int currentAddressNum = 0;
public TcpConnection connection; public TcpConnection connection;
public TcpConnection downloadConnection; public TcpConnection downloadConnection;
...@@ -37,39 +45,148 @@ public class Datacenter { ...@@ -37,39 +45,148 @@ public class Datacenter {
authServerSaltSet = new ArrayList<ServerSalt>(); authServerSaltSet = new ArrayList<ServerSalt>();
} }
public Datacenter(SerializedData data) { public Datacenter(SerializedData data, int version) {
datacenterId = data.readInt32(); if (version == 0) {
address = data.readString(); datacenterId = data.readInt32();
port = data.readInt32(); String address = data.readString();
if (port == 25) { addresses.add(address);
port = 443; int port = data.readInt32();
} ports.put(address, port);
int len = data.readInt32(); int len = data.readInt32();
if (len != 0) { if (len != 0) {
authKey = data.readData(len); authKey = data.readData(len);
} }
len = data.readInt32(); len = data.readInt32();
if (len != 0) { if (len != 0) {
authKeyId = data.readData(len); authKeyId = data.readData(len);
} }
authorized = data.readInt32() != 0; authorized = data.readInt32() != 0;
len = data.readInt32(); len = data.readInt32();
for (int a = 0; a < len; a++) { for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt(); ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32(); salt.validSince = data.readInt32();
salt.validUntil = data.readInt32(); salt.validUntil = data.readInt32();
salt.value = data.readInt64(); salt.value = data.readInt64();
if (authServerSaltSet == null) { if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<ServerSalt>(); authServerSaltSet = new ArrayList<ServerSalt>();
}
authServerSaltSet.add(salt);
}
} else if (version == 1) {
int currentVersion = data.readInt32();
if (currentVersion == 2) {
datacenterId = data.readInt32();
int len = data.readInt32();
for (int a = 0; a < len; a++) {
String address = data.readString();
addresses.add(address);
ports.put(address, data.readInt32());
}
len = data.readInt32();
if (len != 0) {
authKey = data.readData(len);
}
len = data.readInt32();
if (len != 0) {
authKeyId = data.readData(len);
}
authorized = data.readInt32() != 0;
len = data.readInt32();
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<ServerSalt>();
}
authServerSaltSet.add(salt);
}
}
}
readCurrentAddressAndPortNum();
}
public String getCurrentAddress() {
if (addresses.isEmpty()) {
return null;
}
if (currentAddressNum >= addresses.size()) {
currentAddressNum = 0;
}
return addresses.get(currentAddressNum);
}
public int getCurrentPort() {
if (ports.isEmpty()) {
return 443;
}
if (currentPortNum >= defaultPorts.length) {
currentPortNum = 0;
}
int port = defaultPorts[currentPortNum];
if (port == -1) {
String address = getCurrentAddress();
return ports.get(address);
}
return port;
}
public void addAddressAndPort(String address, int port) {
if (addresses.contains(address)) {
return;
}
addresses.add(address);
ports.put(address, port);
}
public void nextAddressOrPort() {
if (currentPortNum + 1 < defaultPorts.length) {
currentPortNum++;
} else {
if (currentAddressNum + 1 < addresses.size()) {
currentAddressNum++;
} else {
currentAddressNum = 0;
} }
authServerSaltSet.add(salt); currentPortNum = 0;
} }
} }
public void storeCurrentAddressAndPortNum() {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("dc" + datacenterId + "port", currentPortNum);
editor.putInt("dc" + datacenterId + "address", currentAddressNum);
editor.commit();
}
});
}
private void readCurrentAddressAndPortNum() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
currentPortNum = preferences.getInt("dc" + datacenterId + "port", 0);
currentAddressNum = preferences.getInt("dc" + datacenterId + "address", 0);
}
public void replaceAddressesAndPorts(ArrayList<String> newAddresses, HashMap<String, Integer> newPorts) {
addresses = newAddresses;
ports = newPorts;
}
public void SerializeToStream(SerializedData stream) { public void SerializeToStream(SerializedData stream) {
stream.writeInt32(DATA_VERSION);
stream.writeInt32(datacenterId); stream.writeInt32(datacenterId);
stream.writeString(address); stream.writeInt32(addresses.size());
stream.writeInt32(port); for (String address : addresses) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}
if (authKey != null) { if (authKey != null) {
stream.writeInt32(authKey.length); stream.writeInt32(authKey.length);
stream.writeRaw(authKey); stream.writeRaw(authKey);
...@@ -129,10 +246,8 @@ public class Datacenter { ...@@ -129,10 +246,8 @@ public class Datacenter {
} }
} }
if (ConnectionsManager.DEBUG_VERSION) { if (result == 0) {
if (result == 0) { FileLog.e("tmessages", "Valid salt not found");
Log.e("tmessages", "Valid salt not found", null);
}
} }
return result; return result;
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -22,7 +22,6 @@ import android.text.Spannable; ...@@ -22,7 +22,6 @@ import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.DynamicDrawableSpan; import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
...@@ -364,7 +363,7 @@ public class Emoji { ...@@ -364,7 +363,7 @@ public class Emoji {
return color; return color;
} catch(Throwable x) { } catch(Throwable x) {
Log.e("tmessages", "Error loading emoji", x); FileLog.e("tmessages", "Error loading emoji", x);
} }
return null; return null;
} }
...@@ -396,7 +395,7 @@ public class Emoji { ...@@ -396,7 +395,7 @@ public class Emoji {
public static Drawable getEmojiDrawable(long code){ public static Drawable getEmojiDrawable(long code){
DrawableInfo info = rects.get(code); DrawableInfo info = rects.get(code);
if(info == null){ if(info == null){
Log.e("tmessages", "No emoji drawable for code " + String.format("%016X", code)); FileLog.e("tmessages", "No emoji drawable for code " + String.format("%016X", code));
return null; return null;
} }
EmojiDrawable ed = new EmojiDrawable(info); EmojiDrawable ed = new EmojiDrawable(info);
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -961,20 +961,15 @@ public class FastDateFormat extends Format { ...@@ -961,20 +961,15 @@ public class FastDateFormat extends Format {
* @return <code>true</code> if equal * @return <code>true</code> if equal
*/ */
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof FastDateFormat == false) { if (!(obj instanceof FastDateFormat)) {
return false; return false;
} }
FastDateFormat other = (FastDateFormat) obj; FastDateFormat other = (FastDateFormat) obj;
if ( return (mPattern == other.mPattern || mPattern.equals(other.mPattern)) &&
(mPattern == other.mPattern || mPattern.equals(other.mPattern)) && (mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) &&
(mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) && (mLocale == other.mLocale || mLocale.equals(other.mLocale)) &&
(mLocale == other.mLocale || mLocale.equals(other.mLocale)) && (mTimeZoneForced == other.mTimeZoneForced) &&
(mTimeZoneForced == other.mTimeZoneForced) && (mLocaleForced == other.mLocaleForced);
(mLocaleForced == other.mLocaleForced)
) {
return true;
}
return false;
} }
/** /**
......
/*
* This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013.
*/
package org.telegram.messenger;
import android.net.Uri;
import android.util.Log;
import org.telegram.ui.ApplicationLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Locale;
public class FileLog {
public static boolean DEBUG_VERSION = true;
public static FileLog Instance = new FileLog();
private OutputStreamWriter streamWriter = null;
private FastDateFormat dateFormat = null;
private DispatchQueue logQueue = null;
private File currentFile = null;
public FileLog() {
if (!DEBUG_VERSION) {
return;
}
dateFormat = FastDateFormat.getInstance("dd_MM_yyyy_HH_mm_ss", Locale.US);
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return;
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
if (dir == null) {
return;
}
dir.mkdirs();
currentFile = new File(dir, dateFormat.format(System.currentTimeMillis()) + ".txt");
if (currentFile == null) {
return;
}
try {
currentFile.createNewFile();
FileOutputStream stream = new FileOutputStream(currentFile);
streamWriter = new OutputStreamWriter(stream);
streamWriter.write("-----start log " + dateFormat.format(System.currentTimeMillis()) + "-----\n");
streamWriter.flush();
logQueue = new DispatchQueue("logQueue");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void e(final String tag, final String message, final Throwable exception) {
if (!DEBUG_VERSION) {
return;
}
Log.e(tag, message, exception);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "﹕ " + message + "\n");
Instance.streamWriter.write(exception.toString());
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void e(final String tag, final String message) {
if (!DEBUG_VERSION) {
return;
}
Log.e(tag, message);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "﹕ " + message + "\n");
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void e(final String tag, final Exception e) {
if (!DEBUG_VERSION) {
return;
}
e.printStackTrace();
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "﹕ " + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (StackTraceElement el : stack) {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "﹕ " + el + "\n");
}
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void d(final String tag, final String message) {
if (!DEBUG_VERSION) {
return;
}
Log.d(tag, message);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " D/" + tag + "﹕ " + message + "\n");
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void cleanupLogs() {
ArrayList<Uri> uris = new ArrayList<Uri>();
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
File dir = new File (sdCard.getAbsolutePath() + "/logs");
File[] files = dir.listFiles();
for (File file : files) {
if (Instance.currentFile != null && file.getAbsolutePath().equals(Instance.currentFile.getAbsolutePath())) {
continue;
}
file.delete();
}
}
}
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -29,15 +29,17 @@ public class FileUploadOperation { ...@@ -29,15 +29,17 @@ public class FileUploadOperation {
private long currentFileId; private long currentFileId;
private boolean isLastPart = false; private boolean isLastPart = false;
private long totalFileSize = 0; private long totalFileSize = 0;
private int totalPartsCount = 0;
private long currentUploaded = 0; private long currentUploaded = 0;
private byte[] key; private byte[] key;
private byte[] iv; private byte[] iv;
private int fingerprint; private int fingerprint;
private boolean isBigFile = false;
FileInputStream stream; FileInputStream stream;
MessageDigest mdEnc = null; MessageDigest mdEnc = null;
public static interface FileUploadOperationDelegate { public static interface FileUploadOperationDelegate {
public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.TL_inputFile inputFile, TLRPC.TL_inputEncryptedFileUploaded inputEncryptedFile); public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
public abstract void didFailedUploadingFile(FileUploadOperation operation); public abstract void didFailedUploadingFile(FileUploadOperation operation);
public abstract void didChangedUploadProgress(FileUploadOperation operation, float progress); public abstract void didChangedUploadProgress(FileUploadOperation operation, float progress);
} }
...@@ -60,14 +62,14 @@ public class FileUploadOperation { ...@@ -60,14 +62,14 @@ public class FileUploadOperation {
} }
fingerprint = Utilities.bytesToInt(fingerprintBytes); fingerprint = Utilities.bytesToInt(fingerprintBytes);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
currentFileId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE); currentFileId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE);
try { try {
mdEnc = MessageDigest.getInstance("MD5"); mdEnc = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
...@@ -95,18 +97,23 @@ public class FileUploadOperation { ...@@ -95,18 +97,23 @@ public class FileUploadOperation {
return; return;
} }
TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart(); TLObject finalRequest;
req.file_part = currentPartNum;
req.file_id = currentFileId;
try { try {
if (stream == null) { if (stream == null) {
File cacheFile = new File(uploadingFilePath); File cacheFile = new File(uploadingFilePath);
stream = new FileInputStream(cacheFile); stream = new FileInputStream(cacheFile);
totalFileSize = cacheFile.length(); totalFileSize = cacheFile.length();
if (totalFileSize > 10 * 1024 * 1024) {
FileLog.e("tmessages", "file is big!");
isBigFile = true;
}
uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))) * 1024; uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))) * 1024;
totalPartsCount = (int)Math.ceil((float)totalFileSize / (float)uploadChunkSize);
readBuffer = new byte[uploadChunkSize]; readBuffer = new byte[uploadChunkSize];
} }
int readed = stream.read(readBuffer); int readed = stream.read(readBuffer);
int toAdd = 0; int toAdd = 0;
if (key != null && readed % 16 != 0) { if (key != null && readed % 16 != 0) {
...@@ -121,14 +128,27 @@ public class FileUploadOperation { ...@@ -121,14 +128,27 @@ public class FileUploadOperation {
sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true); sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true);
} }
mdEnc.update(sendBuffer, 0, readed + toAdd); mdEnc.update(sendBuffer, 0, readed + toAdd);
req.bytes = sendBuffer; if (isBigFile) {
TLRPC.TL_upload_saveBigFilePart req = new TLRPC.TL_upload_saveBigFilePart();
req.file_part = currentPartNum;
req.file_id = currentFileId;
req.file_total_parts = totalPartsCount;
req.bytes = sendBuffer;
finalRequest = req;
} else {
TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart();
req.file_part = currentPartNum;
req.file_id = currentFileId;
req.bytes = sendBuffer;
finalRequest = req;
}
currentUploaded += readed; currentUploaded += readed;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
delegate.didFailedUploadingFile(this); delegate.didFailedUploadingFile(this);
return; return;
} }
requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { requestToken = ConnectionsManager.Instance.performRpc(finalRequest, new RPCRequest.RPCRequestDelegate() {
@Override @Override
public void run(TLObject response, TLRPC.TL_error error) { public void run(TLObject response, TLRPC.TL_error error) {
requestToken = 0; requestToken = 0;
...@@ -139,15 +159,25 @@ public class FileUploadOperation { ...@@ -139,15 +159,25 @@ public class FileUploadOperation {
if (isLastPart) { if (isLastPart) {
state = 3; state = 3;
if (key == null) { if (key == null) {
TLRPC.TL_inputFile result = new TLRPC.TL_inputFile(); TLRPC.InputFile result;
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); if (isBigFile) {
result = new TLRPC.TL_inputFileBig();
} else {
result = new TLRPC.TL_inputFile();
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
}
result.parts = currentPartNum; result.parts = currentPartNum;
result.id = currentFileId; result.id = currentFileId;
result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1); result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1);
delegate.didFinishUploadingFile(FileUploadOperation.this, result, null); delegate.didFinishUploadingFile(FileUploadOperation.this, result, null);
} else { } else {
TLRPC.TL_inputEncryptedFileUploaded result = new TLRPC.TL_inputEncryptedFileUploaded(); TLRPC.InputEncryptedFile result;
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); if (isBigFile) {
result = new TLRPC.TL_inputEncryptedFileBigUploaded();
} else {
result = new TLRPC.TL_inputEncryptedFileUploaded();
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
}
result.parts = currentPartNum; result.parts = currentPartNum;
result.id = currentFileId; result.id = currentFileId;
result.key_fingerprint = fingerprint; result.key_fingerprint = fingerprint;
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
...@@ -144,7 +144,7 @@ public class LruCache { ...@@ -144,7 +144,7 @@ public class LruCache {
evictionCount++; evictionCount++;
} }
String[] args = key.split("$"); String[] args = key.split("@");
if (args.length > 1) { if (args.length > 1) {
ArrayList<String> arr = mapFilters.get(args[0]); ArrayList<String> arr = mapFilters.get(args[0]);
if (arr != null) { if (arr != null) {
...@@ -178,7 +178,7 @@ public class LruCache { ...@@ -178,7 +178,7 @@ public class LruCache {
} }
if (previous != null) { if (previous != null) {
String[] args = key.split("$"); String[] args = key.split("@");
if (args.length > 1) { if (args.length > 1) {
ArrayList<String> arr = mapFilters.get(args[0]); ArrayList<String> arr = mapFilters.get(args[0]);
if (arr != null) { if (arr != null) {
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment