李品

init project

Showing 98 changed files with 4079 additions and 0 deletions

Too many changes to show.

To preserve performance only 98 of 98+ files are displayed.

# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
build/
... ...
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "7f20e5d18ce4cb80c621533090a7c5113f5bdc52"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
base_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
- platform: android
create_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
base_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
- platform: ios
create_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
base_revision: 7f20e5d18ce4cb80c621533090a7c5113f5bdc52
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
... ...
## 0.0.x-dev
* [Developing] Support to use Mars-XLog in flutter project.
## 0.1.0
* Support to use Mars-XLog in flutter project.
## 0.1.1
* Update package description.
\ No newline at end of file
... ...
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
... ...
# flutter_xlog
A plugin for use [Mars-XLog](https://github.com/Tencent/mars) in flutter project.
## Usage
### import package
```
import 'package:flutter_xlog/flutter_xlog.dart'
```
### open XLog
```
await XLog.open(XLogConfig(cacheDir: cacheDir, logDir: logDir, consoleLogOpen: true));
```
### write log
```
XLog.i("MyApp", "build _MyAppState");
```
### close XLog
You maybe want to close XLog because of switch user's account.
```
XLog.close()
```
## Android Issues
### keep XLog classes in proguard file
```
-keep class com.tencent.mars.** {*;}
```
### pick libc++_shared
When you run with debug mode, you may encounter a problem like this:
```
2 files found with path 'lib/arm64-v8a/libc++_shared.so' from inputs:
- xxxx
- xxxx
```
To solve that problem, we recommend you to copy the libc++_shared.so to your app project and then pick it in build.gradle like this:
```
packagingOptions {
pickFirst 'jniLibs/armeabi-v7a/libc++_shared.so'
pickFirst 'jniLibs/arm64-v8a/libc++_shared.so'
}
```
### iOS Issues
Mars-XLog currently does not support iOS simulator. So you can only use it on iphone devices.
... ...
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx
... ...
group 'com.tencent.xlog'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
main.java.srcDirs += 'src/main/java'
main.jniLibs.srcDirs += 'src/main/jniLibs'
}
defaultConfig {
minSdkVersion 19
}
}
... ...
rootProject.name = 'flutter_xlog'
\ No newline at end of file
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tencent.xlog.flutter">
</manifest>
... ...
package com.tencent.mars.xlog;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.widget.Toast;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhaoyuan zhangweizang
*/
public class Log {
private static final String TAG = "mars.xlog.log";
public static final int LEVEL_VERBOSE = 0;
public static final int LEVEL_DEBUG = 1;
public static final int LEVEL_INFO = 2;
public static final int LEVEL_WARNING = 3;
public static final int LEVEL_ERROR = 4;
public static final int LEVEL_FATAL = 5;
public static final int LEVEL_NONE = 6;
// defaults to LEVEL_NONE
private static int level = LEVEL_NONE;
public static Context toastSupportContext = null;
public interface LogImp {
void logV(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
void logI(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
void logD(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
void logW(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
void logE(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
void logF(long logInstancePtr, String tag, String filename, String funcname, int linuxTid, int pid, long tid, long maintid, String log);
int getLogLevel(long logInstancePtr);
void setAppenderMode(long logInstancePtr, int mode);
long openLogInstance(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays);
long getXlogInstance(String nameprefix);
void releaseXlogInstance(String nameprefix);
void appenderOpen(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays);
void appenderClose();
void appenderFlush(long logInstancePtr, boolean isSync);
void setConsoleLogOpen(long logInstancePtr, boolean isOpen);
void setMaxFileSize(long logInstancePtr, long aliveSeconds);
void setMaxAliveTime(long logInstancePtr, long aliveSeconds);
}
private static LogImp debugLog = new LogImp() {
private Handler handler = new Handler(Looper.getMainLooper());
@Override
public void logV(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
if (level <= LEVEL_VERBOSE) {
android.util.Log.v(tag, log);
}
}
@Override
public void logI(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
if (level <= LEVEL_INFO) {
android.util.Log.i(tag, log);
}
}
@Override
public void logD(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
if (level <= LEVEL_DEBUG) {
android.util.Log.d(tag, log);
}
}
@Override
public void logW(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
if (level <= LEVEL_WARNING) {
android.util.Log.w(tag, log);
}
}
@Override
public void logE(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
if (level <= LEVEL_ERROR) {
android.util.Log.e(tag, log);
}
}
@Override
public void logF(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, final String log) {
if (level > LEVEL_FATAL) {
return;
}
android.util.Log.e(tag, log);
if (toastSupportContext != null) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(toastSupportContext, log, Toast.LENGTH_LONG).show();
}
});
}
}
@Override
public int getLogLevel(long logInstancePtr) {
return level;
}
@Override
public void setAppenderMode(long logInstancePtr, int mode) {
}
@Override
public long openLogInstance(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
return 0;
}
@Override
public long getXlogInstance(String nameprefix) {
return 0;
}
@Override
public void releaseXlogInstance(String nameprefix) {
}
@Override
public void appenderOpen(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
}
@Override
public void appenderClose() {
}
@Override
public void appenderFlush(long logInstancePtr, boolean isSync) {
}
@Override
public void setConsoleLogOpen(long logInstancePtr, boolean isOpen) {
}
@Override
public void setMaxAliveTime(long logInstancePtr, long aliveSeconds) {
}
@Override
public void setMaxFileSize(long logInstancePtr, long aliveSeconds) {
}
};
private static LogImp logImp = debugLog;
public static void setLogImp(LogImp imp) {
logImp = imp;
}
public static LogImp getImpl() {
return logImp;
}
public static void appenderOpen(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
if (logImp != null) {
logImp.appenderOpen(level, mode, cacheDir, logDir, nameprefix, cacheDays);
}
}
public static void appenderClose() {
if (logImp != null) {
logImp.appenderClose();
for (Map.Entry<String, LogInstance> entry : sLogInstanceMap.entrySet()) {
closeLogInstance(entry.getKey());
}
}
}
public static void appenderFlush() {
if (logImp != null) {
logImp.appenderFlush(0, false);
for (Map.Entry<String, LogInstance> entry : sLogInstanceMap.entrySet()) {
entry.getValue().appenderFlush();
}
}
}
public static void appenderFlushSync(boolean isSync) {
if (logImp != null) {
logImp.appenderFlush(0, isSync);
}
}
public static int getLogLevel() {
if (logImp != null) {
return logImp.getLogLevel(0);
}
return LEVEL_NONE;
}
public static void setLevel(final int level, final boolean jni) {
Log.level = level;
android.util.Log.w(TAG, "new log level: " + level);
if (jni) {
android.util.Log.e(TAG, "no jni log level support");
}
}
public static void setConsoleLogOpen(boolean isOpen) {
if (logImp != null) {
logImp.setConsoleLogOpen(0, isOpen);
}
}
/**
* use f(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void f(final String tag, final String msg) {
f(tag, msg, (Object[]) null);
}
/**
* use e(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void e(final String tag, final String msg) {
e(tag, msg, (Object[]) null);
}
/**
* use w(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void w(final String tag, final String msg) {
w(tag, msg, (Object[]) null);
}
/**
* use i(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void i(final String tag, final String msg) {
i(tag, msg, (Object[]) null);
}
/**
* use d(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void d(final String tag, final String msg) {
d(tag, msg, (Object[]) null);
}
/**
* use v(tag, format, obj) instead
*
* @param tag
* @param msg
*/
public static void v(final String tag, final String msg) {
v(tag, msg, (Object[]) null);
}
public static void f(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_FATAL) {
final String log = obj == null ? format : String.format(format, obj);
logImp.logF(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void e(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_ERROR) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logE(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void w(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_WARNING) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logW(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void i(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_INFO) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logI(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void d(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_DEBUG) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logD(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void v(String tag, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_VERBOSE) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logV(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public static void printErrStackTrace(String tag, Throwable tr, final String format, final Object... obj) {
if (logImp != null && logImp.getLogLevel(0) <= LEVEL_ERROR) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
log += " " + android.util.Log.getStackTraceString(tr);
logImp.logE(0, tag, "", "", 0, Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
// private static final String SYS_INFO;
// static {
// final StringBuilder sb = new StringBuilder();
// try {
// sb.append("VERSION.RELEASE:[" + android.os.Build.VERSION.RELEASE);
// sb.append("] VERSION.CODENAME:[" + android.os.Build.VERSION.CODENAME);
// sb.append("] VERSION.INCREMENTAL:[" + android.os.Build.VERSION.INCREMENTAL);
// sb.append("] BOARD:[" + android.os.Build.BOARD);
// sb.append("] DEVICE:[" + android.os.Build.DEVICE);
// sb.append("] DISPLAY:[" + android.os.Build.DISPLAY);
// sb.append("] FINGERPRINT:[" + android.os.Build.FINGERPRINT);
// sb.append("] HOST:[" + android.os.Build.HOST);
// sb.append("] MANUFACTURER:[" + android.os.Build.MANUFACTURER);
// sb.append("] MODEL:[" + android.os.Build.MODEL);
// sb.append("] PRODUCT:[" + android.os.Build.PRODUCT);
// sb.append("] TAGS:[" + android.os.Build.TAGS);
// sb.append("] TYPE:[" + android.os.Build.TYPE);
// sb.append("] USER:[" + android.os.Build.USER + "]");
// } catch (Throwable e) {
// e.printStackTrace();
// }
// SYS_INFO = sb.toString();
// }
// public static String getSysInfo() {
// return SYS_INFO;
// }
private static Map<String, LogInstance> sLogInstanceMap = new HashMap<>();
public static LogInstance openLogInstance(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
synchronized (sLogInstanceMap) {
if (sLogInstanceMap.containsKey(nameprefix)) {
return sLogInstanceMap.get(nameprefix);
}
LogInstance instance = new LogInstance(level, mode, cacheDir, logDir, nameprefix, cacheDays);
sLogInstanceMap.put(nameprefix, instance);
return instance;
}
}
public static void closeLogInstance(String prefix) {
synchronized (sLogInstanceMap) {
if (null != logImp) {
if (sLogInstanceMap.containsKey(prefix)) {
LogInstance logInstance = sLogInstanceMap.remove(prefix);
logImp.releaseXlogInstance(prefix);
logInstance.mLogInstancePtr = 0;
}
}
}
}
public static LogInstance getLogInstance(String prefix) {
synchronized (sLogInstanceMap) {
if (sLogInstanceMap.containsKey(prefix)) {
return sLogInstanceMap.get(prefix);
}
return null;
}
}
public static class LogInstance {
private long mLogInstancePtr = 0;
private String mPrefix = null;
private LogInstance(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
if (logImp != null) {
mLogInstancePtr = logImp.openLogInstance(level, mode, cacheDir, logDir, nameprefix, cacheDays);
mPrefix = nameprefix;
}
}
public void f(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_FATAL && mLogInstancePtr != 0) {
final String log = obj == null ? format : String.format(format, obj);
logImp.logF(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void e(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_ERROR && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logE(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void w(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_WARNING && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logW(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void i(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_INFO && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logI(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void d(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_DEBUG && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logD(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void v(String tag, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_VERBOSE && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
logImp.logV(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void printErrStackTrace(String tag, Throwable tr, final String format, final Object... obj) {
if (logImp != null && getLogLevel() <= LEVEL_ERROR && mLogInstancePtr != 0) {
String log = obj == null ? format : String.format(format, obj);
if (log == null) {
log = "";
}
log += " " + android.util.Log.getStackTraceString(tr);
logImp.logE(mLogInstancePtr, tag, "", "", Process.myTid(), Process.myPid(), Thread.currentThread().getId(), Looper.getMainLooper().getThread().getId(), log);
}
}
public void appenderFlush() {
if (logImp != null && mLogInstancePtr != 0) {
logImp.appenderFlush(mLogInstancePtr, false);
}
}
public void appenderFlushSync() {
if (logImp != null && mLogInstancePtr != 0) {
logImp.appenderFlush(mLogInstancePtr, true);
}
}
public int getLogLevel() {
if (logImp != null && mLogInstancePtr != 0) {
return logImp.getLogLevel(mLogInstancePtr);
}
return LEVEL_NONE;
}
public void setConsoleLogOpen(boolean isOpen) {
if (null != logImp && mLogInstancePtr != 0) {
logImp.setConsoleLogOpen(mLogInstancePtr, isOpen);
}
}
}
}
... ...
package com.tencent.mars.xlog;
public class Xlog implements Log.LogImp {
public static final int LEVEL_ALL = 0;
public static final int LEVEL_VERBOSE = 0;
public static final int LEVEL_DEBUG = 1;
public static final int LEVEL_INFO = 2;
public static final int LEVEL_WARNING = 3;
public static final int LEVEL_ERROR = 4;
public static final int LEVEL_FATAL = 5;
public static final int LEVEL_NONE = 6;
public static final int COMPRESS_LEVEL1 = 1;
public static final int COMPRESS_LEVEL2 = 2;
public static final int COMPRESS_LEVEL3 = 3;
public static final int COMPRESS_LEVEL4 = 4;
public static final int COMPRESS_LEVEL5 = 5;
public static final int COMPRESS_LEVEL6 = 6;
public static final int COMPRESS_LEVEL7 = 7;
public static final int COMPRESS_LEVEL8 = 8;
public static final int COMPRESS_LEVEL9 = 9;
public static final int AppednerModeAsync = 0;
public static final int AppednerModeSync = 1;
public static final int ZLIB_MODE = 0;
public static final int ZSTD_MODE = 1;
static class XLoggerInfo {
public int level;
public String tag;
public String filename;
public String funcname;
public int line;
public long pid;
public long tid;
public long maintid;
}
public static class XLogConfig {
public int level = LEVEL_INFO;
public int mode = AppednerModeAsync;
public String logdir;
public String nameprefix;
public String pubkey = "";
public int compressmode = ZLIB_MODE;
public int compresslevel = 0;
public String cachedir;
public int cachedays = 0;
}
public void open(boolean isLoadLib, int level, int mode, String cacheDir, String logDir, String nameprefix, String pubkey) {
if (isLoadLib) {
System.loadLibrary("c++_shared");
System.loadLibrary("marsxlog");
}
XLogConfig logConfig = new XLogConfig();
logConfig.level = level;
logConfig.mode = mode;
logConfig.logdir = logDir;
logConfig.nameprefix = nameprefix;
logConfig.pubkey = pubkey;
logConfig.compressmode = ZLIB_MODE;
logConfig.compresslevel = 0;
logConfig.cachedir = cacheDir;
logConfig.cachedays = 0;
appenderOpen(logConfig);
}
private static String decryptTag(String tag) {
return tag;
}
@Override
public void logV(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_VERBOSE, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void logD(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_DEBUG, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void logI(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_INFO, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void logW(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_WARNING, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void logE(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_ERROR, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void logF(long logInstancePtr, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log) {
logWrite2(logInstancePtr, LEVEL_FATAL, decryptTag(tag), filename, funcname, line, pid, tid, maintid, log);
}
@Override
public void appenderOpen(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
XLogConfig logConfig = new XLogConfig();
logConfig.level = level;
logConfig.mode = mode;
logConfig.logdir = logDir;
logConfig.nameprefix = nameprefix;
logConfig.compressmode = ZLIB_MODE;
logConfig.pubkey = "";
logConfig.cachedir = cacheDir;
logConfig.cachedays = cacheDays;
appenderOpen(logConfig);
}
public static native void logWrite(XLoggerInfo logInfo, String log);
public static void logWrite2(int level, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log){
logWrite2(0, level, tag, filename ,funcname, line, pid, tid, maintid, log);
}
public static native void logWrite2(long logInstancePtr, int level, String tag, String filename, String funcname, int line, int pid, long tid, long maintid, String log);
@Override
public native int getLogLevel(long logInstancePtr);
@Override
public native void setAppenderMode(long logInstancePtr, int mode);
@Override
public long openLogInstance(int level, int mode, String cacheDir, String logDir, String nameprefix, int cacheDays) {
XLogConfig logConfig = new XLogConfig();
logConfig.level = level;
logConfig.mode = mode;
logConfig.logdir = logDir;
logConfig.nameprefix = nameprefix;
logConfig.compressmode = ZLIB_MODE;
logConfig.pubkey = "";
logConfig.cachedir = cacheDir;
logConfig.cachedays = cacheDays;
return newXlogInstance(logConfig);
}
@Override
public native long getXlogInstance(String nameprefix);
@Override
public native void releaseXlogInstance(String nameprefix);
public native long newXlogInstance(XLogConfig logConfig);
@Override
public native void setConsoleLogOpen(long logInstancePtr, boolean isOpen); //set whether the console prints log
public native void appenderOpen(XLogConfig logConfig);
@Override
public native void appenderClose();
@Override
public native void appenderFlush(long logInstancePtr, boolean isSync);
@Override
public native void setMaxFileSize(long logInstancePtr, long aliveSeconds);
@Override
public native void setMaxAliveTime(long logInstancePtr, long aliveSeconds);
}
\ No newline at end of file
... ...
package com.tencent.xlog.flutter
import com.tencent.mars.xlog.Log
import com.tencent.mars.xlog.Xlog
import com.tencent.mars.xlog.Xlog.XLogConfig
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
/** FlutterXLogPlugin */
class FlutterXLogPlugin : FlutterPlugin, MethodCallHandler {
private lateinit var channel: MethodChannel
init {
System.loadLibrary("c++_shared")
System.loadLibrary("marsxlog")
}
private val xlog = Xlog()
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_xlog")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "open") {
val level = call.argument<Int>("level") ?: Log.LEVEL_INFO
val cacheDir = call.argument<String>("cacheDir")
val logDir = call.argument<String>("logDir")
val namePrefix = call.argument<String>("namePrefix")
val cacheDays = call.argument<Int>("cacheDays") ?: 0
val pubKey = call.argument<String>("pubKey");
val consoleLogOpen = call.argument<Boolean>("consoleLogOpen") ?: false
Log.setLogImp(xlog)
Log.setLevel(level, false)
Log.setConsoleLogOpen(consoleLogOpen)
xlog.appenderOpen(XLogConfig().also {
it.level = level
it.cachedir = cacheDir
it.logdir = logDir
it.nameprefix = namePrefix
it.cachedays = cacheDays
it.pubkey = pubKey
})
result.success(null)
} else if (call.method == "flush") {
xlog.appenderFlush(0, true)
result.success(null)
} else if (call.method == "close") {
xlog.appenderClose()
result.success(null)
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}
... ...
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
... ...
# flutter_xlog_example
Demonstrates how to use the flutter_xlog plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
... ...
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
... ...
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "com.tencent.xlog.flutter_xlog_example"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
main.jniLibs.srcDirs += 'src/main/jniLibs'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.tencent.xlog.flutter_xlog_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
packagingOptions {
pickFirst 'jniLibs/armeabi-v7a/libc++_shared.so'
pickFirst 'jniLibs/arm64-v8a/libc++_shared.so'
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {}
... ...
## XLog
-keep class com.tencent.mars.** {*;}
\ No newline at end of file
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="flutter_xlog_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
... ...
package com.tencent.xlog.flutter_xlog_example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
... ...
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
... ...
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-all.zip
... ...
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
}
include ":app"
... ...
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
... ...
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
... ...
PODS:
- Flutter (1.0.0)
- flutter_xlog (0.0.1):
- Flutter
- integration_test (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_xlog (from `.symlinks/plugins/flutter_xlog/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_xlog:
:path: ".symlinks/plugins/flutter_xlog/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_xlog: b23b41d97f3e6b5fce8cdfb26ba915fbd8d45e97
integration_test: 13825b8a9334a850581300559b8839134b124670
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189
COCOAPODS: 1.14.3
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
... ...
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
... ...
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Flutter Xlog</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_xlog_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
... ...
#import "GeneratedPluginRegistrant.h"
... ...
import Flutter
import UIKit
import XCTest
@testable import flutter_xlog
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
class RunnerTests: XCTestCase {
func testGetPlatformVersion() {
let plugin = FlutterXlogPlugin()
let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])
let resultExpectation = expectation(description: "result block must be called.")
plugin.handle(call) { result in
XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion)
resultExpectation.fulfill()
}
waitForExpectations(timeout: 1)
}
}
... ...
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_xlog/flutter_xlog.dart';
import 'package:path_provider/path_provider.dart';
var cacheDir = '';
var logDir = '';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
cacheDir = (await getApplicationCacheDirectory()).path;
logDir = '';
if (Platform.isAndroid) {
logDir = (await getExternalCacheDirectories())?[0].path ?? cacheDir;
} else if (Platform.isIOS) {
logDir = (await getApplicationSupportDirectory()).path;
}
await XLog.open(XLogConfig(cacheDir: cacheDir, logDir: logDir, consoleLogOpen: true));
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
XLog.i("MyApp", "build _MyAppState");
compute((message) {
XLog.i("MyApp", "$message in Isolate");
}, "compute in build");
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('FlutterXLog example app'),
),
body: Column (
children: [
Text('Cached XLog in $cacheDir \nWrite XLog to $logDir \n'),
TextButton(onPressed: () {
XLog.i("MyApp", "click");
XLog.close();
}, child: const Text('close XLog'))
]
),
),
);
}
}
... ...
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.18.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.8"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
ffi:
dependency: "direct main"
description:
name: ffi
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.3"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_driver:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_xlog:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.1.2"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
integration_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.0.4"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.12.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.10"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.0"
platform:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.4"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.8"
process:
dependency: transitive
description:
name: process
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
sync_http:
dependency: transitive
description:
name: sync_http
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.3.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.7.0"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
url: "https://pub.flutter-io.cn"
source: hosted
version: "14.2.1"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
sdks:
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"
... ...
name: flutter_xlog_example
description: "Demonstrates how to use the flutter_xlog plugin."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=3.2.1 <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
flutter_xlog:
# When depending on this package from a real application you should use:
# flutter_xlog: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
path_provider: ^2.1.1
ffi: ^2.1.0
dev_dependencies:
integration_test:
sdk: flutter
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
... ...
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
\ No newline at end of file
... ...
import Flutter
import UIKit
public class FlutterXLogPlugin: NSObject, FlutterPlugin {
var bridge = XLogBridge();
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_xlog", binaryMessenger: registrar.messenger())
let instance = FlutterXLogPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "open":
let params = call.arguments as! [String:Any];
let level = params["level"] as! UInt;
let cacheDir = params["cacheDir"] as! String;
let logDir = params["logDir"] as! String;
let namePrefix = params["namePrefix"] as! String;
let cacheDays = params["cacheDays"] as! UInt;
let consoleLogOpen = params["consoleLogOpen"] as! Bool;
let pubKey = params["pubKey"] as! String;
bridge.open(level, cacheDir: cacheDir, logDir: logDir, prefix: namePrefix, cacheDays: cacheDays, pubKey: pubKey, consoleLogOpen: consoleLogOpen);
result(nil);
case "flush":
bridge.flush();
result(nil);
case "close":
bridge.close();
result(nil);
default:
result(FlutterMethodNotImplemented)
}
}
}
... ...
#import <Foundation/Foundation.h>
@interface XLogBridge: NSObject
- (void)open: (NSUInteger)level cacheDir:(NSString*)cacheDir logDir:(NSString*)logDir prefix:(NSString*)prefix cacheDays:(NSUInteger)cacheDays pubKey:(NSString*)pubKey consoleLogOpen:(BOOL)consoleLogOpen;
- (void)flush;
- (void)close;
@end
... ...
#include <sys/xattr.h>
#import <mars/xlog/xloggerbase.h>
#import <mars/xlog/xlogger.h>
#import <mars/xlog/appender.h>
#import <mars/xlog/xlogger_interface.h>
#import <xlog-swift-bridge.h>
@implementation XLogBridge
- (void)open:(NSUInteger)level cacheDir:(NSString*)cacheDir logDir:(NSString*)logDir prefix:(NSString*)prefix cacheDays:(NSUInteger)cacheDays pubKey:(NSString*)pubKey consoleLogOpen:(BOOL)consoleLogOpen {
xlogger_SetLevel((TLogLevel)level);
mars::xlog::appender_set_console_log(consoleLogOpen);
mars::xlog::XLogConfig config;
config.pub_key_ = [pubKey UTF8String];
config.mode_ = mars::xlog::kAppenderAsync;
config.logdir_ = [logDir UTF8String];
config.nameprefix_ = [prefix UTF8String];
config.compress_mode_ = mars::xlog::kZlib;
config.compress_level_ = 0;
config.cachedir_ = [cacheDir UTF8String];
config.cache_days_ = cacheDays;
mars::xlog::appender_open(config);
//keep Dart_XloggerWrite
Dart_XloggerWrite(0, 2, "FlutterXLog", 0, 0, 0, "Open Flutter XLog.");
}
- (void)flush {
mars::xlog::appender_flush_sync();
}
- (void)close {
mars::xlog::appender_close();
}
@end
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under
// the License.
//
// ThreadOperationQueue.h
// MicroMessenger
//
// Created by yerungui on 12-12-18.
//
#ifndef __MicroMessenger__ThreadOperationQueue__
#define __MicroMessenger__ThreadOperationQueue__
#import <Foundation/Foundation.h>
@interface ThreadQueue : NSObject {
}
+ (BOOL)RunWithTarget:(id)target selector:(SEL)sel object:(id)arg;
@end
extern "C" BOOL RunWithTarget(void (*_funp)(void*), void* _arg);
extern "C" BOOL RunWithTargetNoParam(void (*_fun)());
#endif /* defined(__MicroMessenger__ThreadOperationQueue__) */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COMM_AUTOBUFFER_H_
#define COMM_AUTOBUFFER_H_
#include <string.h>
#include <sys/types.h>
class AutoBuffer {
public:
enum TSeek {
ESeekStart,
ESeekCur,
ESeekEnd,
};
public:
explicit AutoBuffer(size_t _size = 128);
explicit AutoBuffer(void* _pbuffer, size_t _len, size_t _size = 128);
explicit AutoBuffer(const void* _pbuffer, size_t _len, size_t _size = 128);
~AutoBuffer();
void AllocWrite(size_t _readytowrite, bool _changelength = true);
void AddCapacity(size_t _len);
template <class T>
void Write(const T& _val) {
Write(&_val, sizeof(_val));
}
template <class T>
void Write(off_t& _pos, const T& _val) {
Write(_pos, &_val, sizeof(_val));
}
template <class T>
void Write(const off_t& _pos, const T& _val) {
Write(_pos, &_val, sizeof(_val));
}
void Write(const char* const _val) {
Write(_val, strlen(_val));
}
void Write(off_t& _pos, const char* const _val) {
Write(_pos, _val, strlen(_val));
}
void Write(const off_t& _pos, const char* const _val) {
Write(_pos, _val, strlen(_val));
}
void Write(const AutoBuffer& _buffer);
void Write(const void* _pbuffer, size_t _len);
void Write(off_t& _pos, const AutoBuffer& _buffer);
void Write(off_t& _pos, const void* _pbuffer, size_t _len);
void Write(const off_t& _pos, const AutoBuffer& _buffer);
void Write(const off_t& _pos, const void* _pbuffer, size_t _len);
void Write(TSeek _seek, const void* _pbuffer, size_t _len);
template <class T>
size_t Read(T& _val) {
return Read(&_val, sizeof(_val));
}
template <class T>
size_t Read(off_t& _pos, T& _val) const {
return Read(_pos, &_val, sizeof(_val));
}
template <class T>
size_t Read(const off_t& _pos, T& _val) const {
return Read(_pos, &_val, sizeof(_val));
}
size_t Read(void* _pbuffer, size_t _len);
size_t Read(AutoBuffer& _rhs, size_t _len);
size_t Read(off_t& _pos, void* _pbuffer, size_t _len) const;
size_t Read(off_t& _pos, AutoBuffer& _rhs, size_t _len) const;
size_t Read(const off_t& _pos, void* _pbuffer, size_t _len) const;
size_t Read(const off_t& _pos, AutoBuffer& _rhs, size_t _len) const;
off_t Move(off_t _move_len);
void Seek(off_t _offset, TSeek _eorigin);
void Length(off_t _pos, size_t _lenght);
void* Ptr(off_t _offset = 0);
void* PosPtr();
const void* Ptr(off_t _offset = 0) const;
const void* PosPtr() const;
off_t Pos() const;
size_t PosLength() const;
size_t Length() const;
size_t Capacity() const;
void Attach(void* _pbuffer, size_t _len);
void Attach(AutoBuffer& _rhs);
void* Detach(size_t* _plen = NULL);
void Reset();
private:
void __FitSize(size_t _len);
private:
AutoBuffer(const AutoBuffer& _rhs);
AutoBuffer& operator=(const AutoBuffer& _rhs);
private:
unsigned char* parray_;
off_t pos_;
size_t length_;
size_t capacity_;
size_t malloc_unitsize_;
};
extern const AutoBuffer KNullAtuoBuffer;
template <class S>
class copy_wrapper_helper;
template <>
class copy_wrapper_helper<AutoBuffer> {
public:
static void copy_constructor(AutoBuffer& _lhs, AutoBuffer& _rhs) {
_lhs.Attach(_rhs);
}
static void copy_constructor(AutoBuffer& _lhs, const AutoBuffer& _rhs) {
_lhs.Attach(const_cast<AutoBuffer&>(_rhs));
}
static void destructor(AutoBuffer& _delobj) {
}
};
#endif // COMM_AUTOBUFFER_H_
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//
// comm_data.h
// comm
//
// Created by garry on 2017/2/17.
//
#ifndef comm_data_h
#define comm_data_h
#include <stdint.h>
#include <string>
namespace mars {
namespace comm {
enum ProxyType {
kProxyNone = 0,
kProxyHttpTunel,
kProxySocks5,
kProxyHttp,
};
class ProxyInfo {
public:
ProxyInfo() : ProxyInfo(kProxyNone, "", "", 0, "", "") {
}
ProxyInfo(ProxyType _type,
const std::string& _host,
const std::string& _ip,
uint16_t _port,
const std::string& _username,
const std::string& _password)
: type(_type), host(_host), ip(_ip), port(_port), username(_username), password(_password) {
}
bool operator==(const ProxyInfo& _rh) {
if (type != _rh.type) {
return false;
}
if (kProxyNone == type) {
return true;
}
return host == _rh.host && ip == _rh.ip && port == _rh.port && username == _rh.username
&& password == _rh.password;
}
bool IsValid() const {
return kProxyNone == type || ((!ip.empty() || !host.empty()) && port > 0);
}
bool IsAddressValid() const {
return type != kProxyNone && ((!ip.empty() || !host.empty()) && port > 0);
}
public:
ProxyType type;
std::string host;
std::string ip;
uint16_t port;
std::string username;
std::string password;
};
//
enum class BizType{CGI = 0, CDN, COUNT};
enum class ProtoType{TCP = 0, QUIC, COUNT};
struct ConnRecord{
BizType biz = BizType::CGI;
ProtoType proto = ProtoType::TCP;
bool succeed = false; //.是否连接成功.
uint64_t begin_timestamp_ms = 0;
unsigned cost_ms = 0;
};
inline bool operator<(const ConnRecord& lhs, const ConnRecord& rhs){
return lhs.begin_timestamp_ms < rhs.begin_timestamp_ms;
}
} // namespace comm
} // namespace mars
#endif /* comm_data_h */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//============================================================================
// Name : has_member.h
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#ifndef COMM_HAS_MEMBER_H_
#define COMM_HAS_MEMBER_H_
template <bool TYPE>
struct bool_type {};
#define DEFINE_HAS_MEMBER_WITH_TYPE(member_name, member_type) \
template <typename T> \
class has_##member_name { \
private: \
struct yes_type { \
char x[1]; \
}; \
struct no_type { \
char x[2]; \
}; \
template <member_type(T::*)> \
struct tester; \
template <typename U> \
static yes_type test(tester<&U::member_name>*); \
template <typename U> \
static no_type test(...); \
\
public: \
static const bool value = (sizeof(test<T>(0)) == sizeof(yes_type)); \
};
#define DEFINE_HAS_MEMBER(member_name) \
template <typename T> \
class has_##member_name { \
private: \
struct yes_type { \
char x[1]; \
}; \
struct no_type { \
char x[2]; \
}; \
template <int> \
struct tester; \
template <typename U> \
static yes_type test(tester<sizeof(&U::member_name)>*); \
template <typename U> \
static no_type test(...); \
\
public: \
static const bool value = (sizeof(test<T>(0)) == sizeof(yes_type)); \
};
#endif
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
/*
* HttpRequest.h
*
* Created on: 2013-12-5
* Author: yerungui
*/
#ifndef HTTP_H_
#define HTTP_H_
#include <list>
#include <map>
#include <string>
#include "autobuffer.h"
namespace http {
struct less {
bool operator()(const std::string& __x, const std::string& __y) const;
};
enum THttpVersion {
kVersion_0_9,
kVersion_1_0,
kVersion_1_1,
kVersion_2_0,
kVersion_Unknow,
};
const char* const kHttpVersionString[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1",
"HTTP/2",
"version_unknown",
};
enum TCsMode {
kRequest,
kRespond,
};
class RequestLine {
public:
enum THttpMethod {
kUnknown = 0,
kGet,
kPost,
kOptions,
kHead,
kPut,
kDelete,
kTrace,
kConnect,
kMax,
};
static const char* const kHttpMethodString[kMax];
public:
RequestLine();
RequestLine(THttpMethod _httpMethod, const char* _url, THttpVersion _httpVersion);
// RequestLine(const RequestLine&);
// RequestLine& operator=(const RequestLine&);
public:
void Method(THttpMethod _method);
THttpMethod Method() const;
void Version(THttpVersion _version);
THttpVersion Version() const;
void Url(const std::string& _url);
std::string Url() const;
std::string ToString() const;
bool FromString(const std::string& _requestline);
private:
THttpMethod http_method_;
std::string req_url_;
THttpVersion http_version_;
};
class StatusLine {
public:
StatusLine();
StatusLine(THttpVersion _httpversion, int _statuscode, const std::string& _reasonphrase);
// StatusLine(const StatusLine&);
// StatusLine& operator=(const StatusLine&);
public:
void Version(THttpVersion _version);
THttpVersion Version() const;
void StatusCode(int _statuscode);
int StatusCode() const;
void ReasonPhrase(const std::string& _reasonphrase);
std::string ReasonPhrase() const;
std::string ToString() const;
bool FromString(const std::string& _statusline);
private:
THttpVersion http_version_;
int statuscode_;
std::string reason_phrase_;
};
class HeaderFields {
public:
// HeaderFields(const HeaderFields&);
// HeaderFields& operator=(const HeaderFields&);
public:
static std::pair<const std::string, std::string> MakeContentLength(uint64_t _len);
static std::pair<const std::string, std::string> MakeTransferEncodingChunked();
static std::pair<const std::string, std::string> MakeConnectionClose();
static std::pair<const std::string, std::string> MakeConnectionKeepalive();
static std::pair<const std::string, std::string> MakeAcceptAll();
static std::pair<const std::string, std::string> MakeAcceptEncodingDefalte();
static std::pair<const std::string, std::string> MakeAcceptEncodingGzip();
static std::pair<const std::string, std::string> MakeCacheControlNoCache();
static std::pair<const std::string, std::string> MakeContentTypeOctetStream();
static const char* const KStringHost;
static const char* const KStringAccept;
static const char* const KStringUserAgent;
static const char* const KStringCacheControl;
static const char* const KStringConnection;
static const char* const kStringProxyConnection;
static const char* const kStringProxyAuthorization;
static const char* const KStringContentType;
static const char* const KStringContentLength;
static const char* const KStringTransferEncoding;
static const char* const kStringContentEncoding;
static const char* const KStringAcceptEncoding;
static const char* const KStringContentRange;
static const char* const KStringMicroMessenger;
static const char* const KStringRange;
static const char* const KStringLocation;
static const char* const KStringReferer;
static const char* const kStringServer;
static const char* const KStringKeepalive;
void HeaderFiled(const char* _name, const char* _value);
void HeaderFiled(const std::pair<const std::string, std::string>& _headerfield);
void InsertOrUpdate(const std::pair<const std::string, std::string>& _headerfield);
void Manipulate(const std::pair<const std::string, std::string>& _headerfield);
const char* HeaderField(const char* _key) const;
void CopyFrom(const HeaderFields& rhs);
std::map<const std::string, std::string, less>& GetHeaders() {
return headers_;
}
std::list<std::pair<const std::string, const std::string>> GetAsList() const;
bool IsTransferEncodingChunked() const;
bool IsConnectionClose() const;
bool IsConnectionKeepAlive() const;
uint64_t ContentLength() const;
uint32_t KeepAliveTimeout() const;
bool Range(long& _start, long& _end) const;
bool ContentRange(uint64_t* start, uint64_t* end, uint64_t* total) const;
static bool ContentRange(const std::string& line, uint64_t* start, uint64_t* end, uint64_t* total);
const std::string ToString() const;
private:
std::map<const std::string, std::string, less> headers_;
};
class IBlockBodyProvider {
public:
virtual ~IBlockBodyProvider() {
}
virtual bool Data(AutoBuffer& _body) = 0;
virtual bool FillData(AutoBuffer& _body) = 0;
virtual size_t Length() const = 0;
};
class BufferBodyProvider : public IBlockBodyProvider {
public:
bool Data(AutoBuffer& _body) {
if (!_body.Ptr())
return false;
buffer_.Write(_body.Ptr(), _body.Length());
_body.Reset();
return true;
}
bool FillData(AutoBuffer& _body) {
if (!buffer_.Ptr())
return false;
_body.Write(buffer_.Ptr(), buffer_.Length());
buffer_.Reset();
return true;
}
size_t Length() const {
return buffer_.Length();
}
AutoBuffer& Buffer() {
return buffer_;
}
private:
AutoBuffer buffer_;
};
class IStreamBodyProvider {
public:
virtual ~IStreamBodyProvider() {
}
virtual bool HaveData() const = 0;
virtual bool Data(AutoBuffer& _body) = 0;
virtual bool Eof() const = 0;
const char* EofData();
protected:
static void AppendHeader(AutoBuffer& _body, size_t _length);
static void AppendTail(AutoBuffer& _body);
};
class Builder {
public:
Builder(TCsMode _csmode);
~Builder();
private:
Builder(const Builder&);
Builder& operator=(const Builder&);
public:
RequestLine& Request();
StatusLine& Status();
const RequestLine& Request() const;
const StatusLine& Status() const;
HeaderFields& Fields();
const HeaderFields& Fields() const;
void BlockBody(IBlockBodyProvider* _body, bool _manage);
void StreamBody(IStreamBodyProvider* _body, bool _manage);
IBlockBodyProvider* BlockBody();
IStreamBodyProvider* StreamBody();
const IBlockBodyProvider* BlockBody() const;
const IStreamBodyProvider* StreamBody() const;
bool HeaderToBuffer(AutoBuffer& _header);
bool HttpToBuffer(AutoBuffer& _http);
private:
TCsMode csmode_;
StatusLine statusline_;
RequestLine requestline_;
HeaderFields headfields_;
IBlockBodyProvider* blockbody_;
IStreamBodyProvider* streambody_;
bool is_manage_body_;
};
class BodyReceiver {
public:
BodyReceiver() : total_length_(0) {
}
virtual ~BodyReceiver() {
}
virtual void AppendData(const void* _body, size_t _length) {
total_length_ += _length;
}
virtual void EndData() {
}
size_t Length() const {
return total_length_;
}
private:
size_t total_length_;
};
class MemoryBodyReceiver : public BodyReceiver {
public:
MemoryBodyReceiver(AutoBuffer& _buf) : body_(_buf) {
}
virtual void AppendData(const void* _body, size_t _length) {
BodyReceiver::AppendData(_body, _length);
body_.Write(_body, _length);
}
virtual void EndData() {
}
private:
AutoBuffer& body_;
};
class Parser {
public:
enum TRecvStatus {
kStart,
kFirstLine,
kFirstLineError,
kHeaderFields,
kHeaderFieldsError,
kBody,
kBodyError,
kEnd,
};
public:
Parser(BodyReceiver* _body = new BodyReceiver(), bool _manage = true);
~Parser();
private:
Parser(const Parser&);
Parser& operator=(const Parser&);
public:
TRecvStatus Recv(const void* _buffer,
size_t _length,
size_t* consumed_bytes = nullptr,
bool only_parse_header = false);
TRecvStatus Recv(AutoBuffer& _recv_buffer);
TRecvStatus RecvStatus() const;
TCsMode CsMode() const;
bool FirstLineReady() const;
const RequestLine& Request() const;
const StatusLine& Status() const;
const AutoBuffer& HeaderBuffer() const;
bool FieldsReady() const;
HeaderFields& Fields();
const HeaderFields& Fields() const;
size_t FirstLineLength() const;
size_t HeaderLength() const;
bool BodyReady() const;
bool BodyRecving() const;
BodyReceiver& Body();
const BodyReceiver& Body() const;
bool Error() const;
bool Success() const;
private:
TRecvStatus recvstatus_;
AutoBuffer recvbuf_;
AutoBuffer headerbuf_;
bool response_header_ready_;
TCsMode csmode_;
StatusLine statusline_;
RequestLine requestline_;
HeaderFields headfields_;
BodyReceiver* bodyreceiver_;
bool is_manage_body_;
size_t firstlinelength_;
size_t headerlength_;
};
// void testChunk();
} /* namespace http */
#endif /* HTTPREQUEST_H_ */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//
// IPv6_only.hpp
// comm
//
// Created by yerungui on 16/1/14.
//
#ifndef __ip_type__
#define __ip_type__
#ifdef __cplusplus
extern "C" {
#endif
enum TLocalIPStack {
ELocalIPStack_None = 0,
ELocalIPStack_IPv4 = 1,
ELocalIPStack_IPv6 = 2,
ELocalIPStack_Dual = 3,
};
const char* const TLocalIPStackStr[] = {
"ELocalIPStack_None",
"ELocalIPStack_IPv4",
"ELocalIPStack_IPv6",
"ELocalIPStack_Dual",
};
TLocalIPStack local_ipstack_detect();
#ifdef __cplusplus
}
#endif
#include <string>
TLocalIPStack local_ipstack_detect_log(std::string& _log);
#endif /* __ip_type__ */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
/*
* nat64_prefix_util.h
*
* Created on: 2016年6月22日
* Author: wutianqiang
*/
#ifndef SOCKET_NAT64_PREFIX_UTIL_H_
#define SOCKET_NAT64_PREFIX_UTIL_H_
/*
* WARNING:All functions below may be blocked when called first time, please don't use these functions in main thread.
* if current network is not ipv6-only, these fuction all will return false
* */
#include <string>
#ifdef __APPLE__
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
#endif
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif
/*
* param: _nat64_prefix, return the nat64 prefix, using a string
* return: if return false, then _nat64_prfix is empty string.
* */
bool GetNetworkNat64Prefix(std::string& _nat64_prefix);
/*
* param: _nat64_prefix_in6, return the nat64 prefix, using struct in6_addr.
* _nat64_prefix_in6.s6_addr32[0~2](12 Bytes) contain the nat64 prefix
* return: if return false, _nat64_prefix_in6 will not change.
* */
bool GetNetworkNat64Prefix(struct in6_addr& _nat64_prefix_in6);
/*
* param: _v4_ip:the input v4 ip, _nat64_v6_ip the output v6 ip, which embeded _v4_ip with format RFC6052
* return: if return false(MAY BE INVALID _v4_ip), _nat64_v6_ip will not change.
* */
bool ConvertV4toNat64V6(const std::string& _v4_ip, std::string& _nat64_v6_ip);
/*
* param: _v4_addr input v4 addr, _v6_addr the output v6 addr, which embeded _v4_addr with format RFC6052
* return: if return false, _v6_addr will not change.
* */
bool ConvertV4toNat64V6(const struct in_addr& _v4_addr, struct in6_addr& _v6_addr);
#endif /* SOCKET_NAT64_PREFIX_UTIL_H_ */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//
// prjdef.h
// comm
//
// Created by yerungui on 16/4/26.
// Copyright © 2016年 Tencent. All rights reserved.
//
#ifndef prjdef_h
#define prjdef_h
#ifdef _WIN32
#include "windows/projdef.h"
#endif
#endif /* prjdef_h */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
//
// scope_autoreleasepool.h
// MicroMessenger
//
// Created by yerungui on 12-11-30.
//
#ifndef __MicroMessenger__scope_autoreleasepool__
#define __MicroMessenger__scope_autoreleasepool__
class Scope_AutoReleasePool {
public:
Scope_AutoReleasePool();
~Scope_AutoReleasePool();
private:
Scope_AutoReleasePool(const Scope_AutoReleasePool&);
Scope_AutoReleasePool& operator=(const Scope_AutoReleasePool&);
private:
id m_pool;
};
#define SCOPE_POOL() Scope_AutoReleasePool __pool__##__LINE__
#endif /* defined(__MicroMessenger__scope_autoreleasepool__) */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
/*
Author : yerungui
Created on : 2016-04-14
*/
#ifndef STRING_CAST_H_
#define STRING_CAST_H_
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#define __STDC_FORMAT_MACROS
#include <strings.h>
#else
#include "projdef.h"
#endif
#include <inttypes.h>
#include <string.h>
#include <limits>
#include <string>
#include "strutil.h"
template <typename T>
char* string_cast_itoa(const T& value, char* result, uint8_t base = 10, bool upper_case = true) {
if (!(2 <= base && base <= 36)) {
#if defined(_WIN32)
strcpy_s(result, strlen(result), "itoa err");
#else
strcpy(result, "itoa err");
#endif
return result;
}
char *ptr_right = result, *ptr_left = result;
T tmp_value = value;
const char* num_mapping;
if (upper_case)
num_mapping = "ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
else
num_mapping = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz";
do {
T quotient = tmp_value / base;
*(ptr_right++) = num_mapping[35 + tmp_value - quotient * base];
tmp_value = quotient;
} while (tmp_value);
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif
if (value < 0)
*(ptr_right++) = '-';
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
*(ptr_right--) = '\0';
while (ptr_left < ptr_right) {
char tmp_char = *ptr_right;
*(ptr_right--) = *ptr_left;
*(ptr_left++) = tmp_char;
}
return result;
}
#define string_cast_hex(value) string_cast(value, 16)
#define string_cast_oct(value) string_cast(value, 8)
class string_cast {
public:
string_cast(char _value) : value_(NULL) {
value_cache_[0] = _value;
value_cache_[1] = '\0';
value_ = value_cache_;
}
string_cast(int _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(long _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(long long _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(unsigned int _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(unsigned long _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(unsigned long long _value, uint8_t base = 10) : value_(NULL) {
string_cast_itoa(_value, value_cache_, base);
value_ = value_cache_;
}
string_cast(float _value) : value_(NULL) {
snprintf(value_cache_, sizeof(value_cache_), "%.2f", _value);
value_ = value_cache_;
}
string_cast(double _value) : value_(NULL) {
snprintf(value_cache_, sizeof(value_cache_), "%.2f", _value);
value_ = value_cache_;
}
string_cast(long double _value) : value_(NULL) {
snprintf(value_cache_, sizeof(value_cache_), "%.2Lf", _value);
value_ = value_cache_;
}
string_cast(bool _value) : value_(NULL) {
if (_value)
value_ = "true";
else
value_ = "false";
value_cache_[0] = '\0';
}
string_cast(const void* _value) : value_(NULL) {
value_cache_[0] = '0';
value_cache_[1] = 'x';
string_cast_itoa((uintptr_t)_value, value_cache_ + 2, 16);
value_ = value_cache_;
}
string_cast(const char* _value) : value_(NULL) {
value_ = (const char*)_value;
value_cache_[0] = '\0';
}
string_cast(const std::string& _value) : value_(NULL) {
value_ = _value.c_str();
value_cache_[0] = '\0';
}
const char* str() const {
return value_;
}
operator const char*() const {
return value_;
}
private:
string_cast(const string_cast&);
string_cast& operator=(const string_cast&);
private:
const char* value_;
char value_cache_[65];
};
namespace detail {
template <typename T, int base = 0>
class __signed_number_cast {
public:
__signed_number_cast(const char* _str) : value_(0), vaild_(false) {
if (_str == NULL)
return;
char* end = NULL;
vaild_ = true;
value_ = strtoimax(_str, &end, base);
if (_str == end) {
vaild_ = false;
return;
}
if (value_ < (std::numeric_limits<T>::min)()) {
value_ = (std::numeric_limits<T>::min)();
vaild_ = false;
return;
}
if ((std::numeric_limits<T>::max)() < value_) {
value_ = (std::numeric_limits<T>::max)();
vaild_ = false;
return;
}
}
operator T() const {
return static_cast<T>(value_);
}
bool valid() const {
return vaild_;
}
private:
intmax_t value_;
bool vaild_;
};
template <typename T, int base = 0>
class __unsigned_number_cast {
public:
__unsigned_number_cast(const char* _str) : value_(0), vaild_(false) {
if (_str == NULL)
return;
char* end = NULL;
vaild_ = true;
value_ = strtoumax(_str, &end, base);
if (_str == end) {
vaild_ = false;
return;
}
if (value_ < (std::numeric_limits<T>::min)()) {
value_ = (std::numeric_limits<T>::min)();
vaild_ = false;
return;
}
if ((std::numeric_limits<T>::max)() < value_) {
value_ = (std::numeric_limits<T>::max)();
vaild_ = false;
return;
}
}
operator T() const {
return static_cast<T>(value_);
}
bool valid() const {
return vaild_;
}
private:
uintmax_t value_;
bool vaild_;
};
template <typename T>
class __float_number_cast {
public:
__float_number_cast(const char* _str) : value_(0), vaild_(false) {
if (_str == NULL)
return;
char* end = NULL;
vaild_ = true;
value_ = strtod(_str, &end);
if (_str == end) {
vaild_ = false;
}
}
operator T() const {
return static_cast<T>(value_);
}
bool valid() const {
return vaild_;
}
private:
double value_;
bool vaild_;
};
} // namespace detail
template <typename T>
class number_cast {};
template <>
class number_cast<int8_t> : public detail::__signed_number_cast<int8_t> {
public:
number_cast(const char* _str) : __signed_number_cast(_str){};
};
template <>
class number_cast<int16_t> : public detail::__signed_number_cast<int16_t> {
public:
number_cast(const char* _str) : __signed_number_cast(_str){};
};
template <>
class number_cast<int32_t> : public detail::__signed_number_cast<int32_t> {
public:
number_cast(const char* _str) : __signed_number_cast(_str){};
};
template <>
class number_cast<long> : public detail::__signed_number_cast<long> {
public:
number_cast(const char* _str) : __signed_number_cast(_str){};
};
template <>
class number_cast<long long> : public detail::__signed_number_cast<long long> {
public:
number_cast(const char* _str) : __signed_number_cast(_str){};
};
template <>
class number_cast<uint8_t> : public detail::__unsigned_number_cast<uint8_t> {
public:
number_cast(const char* _str) : __unsigned_number_cast(_str){};
};
template <>
class number_cast<uint16_t> : public detail::__unsigned_number_cast<uint16_t> {
public:
number_cast(const char* _str) : __unsigned_number_cast(_str){};
};
template <>
class number_cast<uint32_t> : public detail::__unsigned_number_cast<uint32_t> {
public:
number_cast(const char* _str) : __unsigned_number_cast(_str){};
};
template <>
class number_cast<unsigned long> : public detail::__unsigned_number_cast<unsigned long> {
public:
number_cast(const char* _str) : __unsigned_number_cast(_str){};
};
template <>
class number_cast<unsigned long long> : public detail::__unsigned_number_cast<unsigned long long> {
public:
number_cast(const char* _str) : __unsigned_number_cast(_str){};
};
template <>
class number_cast<float> : public detail::__float_number_cast<float> {
public:
number_cast(const char* _str) : __float_number_cast(_str){};
};
template <>
class number_cast<double> : public detail::__float_number_cast<double> {
public:
number_cast(const char* _str) : __float_number_cast(_str){};
};
template <>
class number_cast<const char*> {
public:
number_cast(const char* _str) : value_(NULL), vaild_(false) {
if (_str == NULL)
return;
value_ = _str;
vaild_ = true;
}
operator const char*() const {
return value_;
}
bool valid() const {
return vaild_;
}
private:
const char* value_;
bool vaild_;
};
template <>
class number_cast<bool> {
public:
number_cast(const char* _str) : value_(false), vaild_(false) {
if (_str == NULL)
return;
std::vector<std::string> vec_split;
strutil::SplitToken(_str, strutil::default_delimiters<std::string>::value(), vec_split);
if (vec_split.empty()) {
return;
}
if (vec_split[0] == "1" || 0 == strcasecmp("true", vec_split[0].c_str())) {
vaild_ = true;
value_ = true;
}
if (vec_split[0] == "0" || 0 == strcasecmp("false", vec_split[0].c_str())) {
vaild_ = true;
value_ = false;
}
}
operator bool() const {
return value_;
}
bool valid() const {
return vaild_;
}
private:
bool value_;
bool vaild_;
};
#endif /* STRING_CAST_H_ */
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// @(#) strutil.h
// Utilities for string
// defined in namespace strutil
// Support for Symbian
// yerungui
////////////////////////////////////////////////////////////////////////////////
#ifndef COMM_STRUTIL_H_
#define COMM_STRUTIL_H_
#include <string>
#include <vector>
// declaration
namespace strutil {
/////////////////////// string /////////////////////////////
std::string& URLEncode(const std::string& url, std::string& encodeUrl);
std::string& TrimLeft(std::string& str);
std::string& TrimRight(std::string& str);
std::string& Trim(std::string& str);
std::string& ToLower(std::string& str);
std::string& ToUpper(std::string& str);
bool StartsWith(const std::string& str, const std::string& substr);
bool EndsWith(const std::string& str, const std::string& substr);
std::vector<std::string>& SplitToken(const std::string& str,
const std::string& delimiters,
std::vector<std::string>& ss);
// T1 is iterator, T2 is string or wstring
template <typename T1, typename T2>
bool MergeToken(const T1& begin, const T1& end, const T2& delimiter, T2& result);
/////////////////////// wstring /////////////////////////////
std::wstring& TrimLeft(std::wstring& str);
std::wstring& TrimRight(std::wstring& str);
std::wstring& Trim(std::wstring& str);
bool StartsWith(const std::wstring& str, const std::wstring& substr);
bool EndsWith(const std::wstring& str, const std::wstring& substr);
std::wstring& ToLower(std::wstring& str);
std::wstring& ToUpper(std::wstring& str);
#ifdef WIN32
std::wstring String2WString(const std::string& _src, unsigned int _cp);
std::wstring UTF8String2Wstring(const std::string& _src);
#endif
std::vector<std::wstring>& SplitToken(const std::wstring& str,
const std::wstring& delimiters,
std::vector<std::wstring>& ss);
// Tokenizer class
template <class T>
struct default_delimiters {};
template <>
struct default_delimiters<std::string> {
static const char* value() {
return " \t\n\r;:,.?";
}
};
template <>
struct default_delimiters<std::wstring> {
static const wchar_t* value() {
return L" \t\n\r;:,.?";
}
};
template <class T>
class Tokenizer {
public:
Tokenizer(const T& str, const T& delimiters = default_delimiters<T>::value())
: offset_(0), string_(str), delimiters_(delimiters) {
}
void Reset() {
offset_ = 0;
}
const T GetToken() const {
return token_;
}
bool NextToken() {
return NextToken(delimiters_);
}
bool NextToken(const T& delimiters) {
// find the start charater of the next token.
typename T::size_type i = string_.find_first_not_of(delimiters, offset_);
if (i == T::npos) {
offset_ = string_.length();
return false;
}
// find the end of the token.
typename T::size_type j = string_.find_first_of(delimiters, i);
if (j == T::npos) {
token_ = string_.substr(i, string_.length() - i);
offset_ = string_.length();
return true;
}
// to intercept the token and save current position
token_ = string_.substr(i, j - i);
offset_ = j;
return true;
}
private:
Tokenizer(const Tokenizer&);
Tokenizer& operator=(const Tokenizer&);
protected:
typename T::size_type offset_;
const T string_;
T token_;
T delimiters_;
};
template <typename T1, typename T2>
bool MergeToken(const T1& begin, const T1& end, const T2& delimiter, T2& result) {
if (begin == end) {
return false;
}
if (delimiter.empty()) {
return false;
}
result.clear();
for (T1 iter = begin; iter != end; ++iter) {
result += *iter;
if (iter + 1 != end) {
result += delimiter;
}
}
return true;
}
std::string Hex2Str(const char* _str, unsigned int _len);
std::string Str2Hex(const char* _str, unsigned int _len);
std::string ReplaceChar(const char* const input_str, char be_replaced = '@', char replace_with = '.');
std::string GetFileNameFromPath(const char* _path);
// find substring (case insensitive)
size_t ci_find_substr(const std::string& str, const std::string& sub, size_t pos);
std::string BufferMD5(const void* buffer, size_t size);
std::string MD5DigestToBase16(const uint8_t digest[16]);
std::string DigestToBase16(const uint8_t* digest, size_t length);
} // namespace strutil
#endif // COMM_STRUTIL_H_
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
/*
* utils.h
*
* Created on: 2012-7-18
* Author: yerungui
*/
#ifndef COMM_UTILS_H_
#define COMM_UTILS_H_
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
uint64_t gettickcount(); // ms
int64_t gettickspan(uint64_t _old_tick); // ms
uint64_t timeMs();
uint64_t clock_app_monotonic(); // ms
#ifdef __cplusplus
}
#endif
#endif /* COMM_UTILS_H_ */
... ...
#ifndef Mars_verinfo_h
#define Mars_verinfo_h
#define MARS_REVISION "69c2439f"
#define MARS_PATH "master"
#define MARS_URL ""
#define MARS_BUILD_TIME "2023-12-05 00:28:00"
#define MARS_TAG ""
#endif
... ...
// Tencent is pleased to support the open source community by making Mars available.
// Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
// Licensed under the MIT License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://opensource.org/licenses/MIT
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
/*
* appender.h
*
* Created on: 2013-3-7
* Author: yerungui
*/
#ifndef APPENDER_H_
#define APPENDER_H_
#include <stdint.h>
#include <string>
#include <vector>
namespace mars {
namespace xlog {
enum TAppenderMode {
kAppenderAsync,
kAppenderSync,
};
enum TCompressMode {
kZlib,
kZstd,
};
enum TFileIOAction {
kActionNone = 0,
kActionSuccess = 1,
kActionUnnecessary = 2,
kActionOpenFailed = 3,
kActionReadFailed = 4,
kActionWriteFailed = 5,
kActionCloseFailed = 6,
kActionRemoveFailed = 7,
};
struct XLogConfig {
TAppenderMode mode_ = kAppenderAsync;
std::string logdir_;
std::string nameprefix_;
std::string pub_key_;
TCompressMode compress_mode_ = kZlib;
int compress_level_ = 6;
std::string cachedir_;
int cache_days_ = 0;
};
#ifdef __APPLE__
enum TConsoleFun {
kConsolePrintf,
kConsoleNSLog,
};
#endif
void appender_open(const XLogConfig& _config);
void appender_flush();
void appender_flush_sync();
void appender_close();
void appender_setmode(TAppenderMode _mode);
bool appender_getfilepath_from_timespan(int _timespan, const char* _prefix, std::vector<std::string>& _filepath_vec);
bool appender_make_logfile_name(int _timespan, const char* _prefix, std::vector<std::string>& _filepath_vec);
bool appender_get_current_log_path(char* _log_path, unsigned int _len);
bool appender_get_current_log_cache_path(char* _logPath, unsigned int _len);
void appender_set_console_log(bool _is_open);
#ifdef __APPLE__
void appender_set_console_fun(TConsoleFun _fun);
#endif
/*
* By default, all logs will write to one file everyday. You can split logs to multi-file by changing max_file_size.
*
* @param _max_byte_size Max byte size of single log file, default is 0, meaning do not split.
*/
void appender_set_max_file_size(uint64_t _max_byte_size);
/*
* By default, all logs lives 10 days at most.
*
* @param _max_time Max alive duration of a single log file in seconds, default is 10 days
*/
void appender_set_max_alive_duration(long _max_time);
void appender_oneshot_flush(const XLogConfig& _config, TFileIOAction* _result);
} // namespace xlog
} // namespace mars
#endif /* APPENDER_H_ */
... ...