Browse Source

Added support for fsyncing a directory.

Bob Lee 9 years ago
parent
commit
9c195d377f

+ 1
- 0
.idea/modules.xml View File

@@ -6,6 +6,7 @@
6 6
       <module fileurl="file://$PROJECT_DIR$/modules/core/core.iml" filepath="$PROJECT_DIR$/modules/core/core.iml" />
7 7
       <module fileurl="file://$PROJECT_DIR$/modules/http/http.iml" filepath="$PROJECT_DIR$/modules/http/http.iml" />
8 8
       <module fileurl="file://$PROJECT_DIR$/modules/io/io.iml" filepath="$PROJECT_DIR$/modules/io/io.iml" />
9
+      <module fileurl="file://$PROJECT_DIR$/modules/android/test_app/test_app.iml" filepath="$PROJECT_DIR$/modules/android/test_app/test_app.iml" />
9 10
     </modules>
10 11
   </component>
11 12
 </project>

+ 2
- 0
modules/android/.gitignore View File

@@ -0,0 +1,2 @@
1
+android-ndk
2
+obj

+ 13
- 0
modules/android/README.jni View File

@@ -0,0 +1,13 @@
1
+The native portions of Retofit's Android module live in ./jni.
2
+
3
+Building:
4
+
5
+  ./build-jni.sh
6
+
7
+Installation:
8
+
9
+  Copy ./libs to your Android project root.
10
+
11
+Testing:
12
+
13
+  Run test_app on a device or emulator.

+ 13
- 0
modules/android/build-jni.sh View File

@@ -0,0 +1,13 @@
1
+#!/bin/sh
2
+
3
+if [ ! -d android-ndk ]
4
+then
5
+  echo Downloading Android NDK...
6
+  curl http://dl.google.com/android/ndk/android-ndk-r5b-darwin-x86.tar.bz2 > /tmp/android-ndk.tgz
7
+  tar zxf /tmp/android-ndk.tgz -C /tmp
8
+  echo Extracting Android NDK...
9
+  mv /tmp/android-ndk-r5b ./android-ndk
10
+fi
11
+
12
+./android-ndk/ndk-build
13
+

+ 8
- 0
modules/android/jni/Android.mk View File

@@ -0,0 +1,8 @@
1
+LOCAL_PATH := $(call my-dir)
2
+
3
+include $(CLEAR_VARS)
4
+
5
+LOCAL_MODULE    := retrofit
6
+LOCAL_SRC_FILES := retrofit.c
7
+
8
+include $(BUILD_SHARED_LIBRARY)

+ 30
- 0
modules/android/jni/retrofit.c View File

@@ -0,0 +1,30 @@
1
+#include <string.h>
2
+#include <jni.h>
3
+#include <errno.h>
4
+#include <fcntl.h>
5
+
6
+static void throwException(JNIEnv* env, const char* typeName,
7
+    const char* message) {
8
+  (*env)->ThrowNew(env, (*env)->FindClass(env, typeName), message);
9
+}
10
+
11
+void Java_retrofit_io_Native_sync(JNIEnv* env, jclass javaType,
12
+    jstring javaPath) {
13
+  const char* path = (*env)->GetStringUTFChars(env, javaPath, NULL);
14
+  // assert path != NULL
15
+
16
+  // Returns an error if path doesn't reference a directory.
17
+  int fd = open(path, O_RDONLY | O_DIRECTORY);
18
+
19
+  (*env)->ReleaseStringUTFChars(env, javaPath, path);
20
+
21
+  if (fd == -1) goto io_error;
22
+  if (fsync(fd) == -1) goto io_error;
23
+  if (close(fd) == -1) goto io_error;
24
+
25
+  return;
26
+
27
+io_error:
28
+  throwException(env, "java/io/IOException", strerror(errno));
29
+  return;
30
+}

BIN
modules/android/libs/armeabi/libretrofit.so View File


+ 3
- 0
modules/android/test_app/.gitignore View File

@@ -0,0 +1,3 @@
1
+libs
2
+gen
3
+bin

+ 15
- 0
modules/android/test_app/AndroidManifest.xml View File

@@ -0,0 +1,15 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+      package="retrofit.test_app"
4
+      android:versionCode="1"
5
+      android:versionName="1.0">
6
+    <application android:label="Test Retrofit">
7
+        <activity android:name="Main"
8
+                  android:label="Test Retrofit">
9
+            <intent-filter>
10
+                <action android:name="android.intent.action.MAIN" />
11
+                <category android:name="android.intent.category.LAUNCHER" />
12
+            </intent-filter>
13
+        </activity>
14
+    </application>
15
+</manifest> 

+ 17
- 0
modules/android/test_app/build.properties View File

@@ -0,0 +1,17 @@
1
+# This file is used to override default values used by the Ant build system.
2
+#
3
+# This file must be checked in Version Control Systems, as it is
4
+# integral to the build system of your project.
5
+
6
+# This file is only used by the Ant script.
7
+
8
+# You can use this to override default values such as
9
+#  'source.dir' for the location of your java source folder and
10
+#  'out.dir' for the location of your output folder.
11
+
12
+# You can also use it define how the release builds are signed by declaring
13
+# the following properties:
14
+#  'key.store' for the location of your keystore and
15
+#  'key.alias' for the name of the key to use.
16
+# The password will be asked during the build when you use the 'release' target.
17
+

+ 94
- 0
modules/android/test_app/build.xml View File

@@ -0,0 +1,94 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project name="test_app" default="help">
3
+
4
+  <target name="-pre-build">
5
+    <mkdir dir="libs"/>
6
+
7
+    <!-- Copy native library. -->
8
+    <copy todir="libs/armeabi">
9
+      <fileset dir="../libs/armeabi"/>
10
+    </copy>
11
+
12
+    <!-- Copy Retrofit's Java library. -->
13
+    <copy todir="libs">
14
+      <fileset dir="../../../build" includes="retrofit-io*.jar"
15
+          excludes="*src*"/>
16
+    </copy>
17
+  </target>
18
+
19
+<!-- The local.properties file is created and updated by the 'android'
20
+     tool.
21
+     It contains the path to the SDK. It should *NOT* be checked into
22
+     Version Control Systems. -->
23
+    <property file="local.properties" />
24
+
25
+    <!-- The build.properties file can be created by you and is never touched
26
+         by the 'android' tool. This is the place to change some of the
27
+         default property values used by the Ant rules.
28
+         Here are some properties you may want to change/update:
29
+
30
+         source.dir
31
+             The name of the source directory. Default is 'src'.
32
+         out.dir
33
+             The name of the output directory. Default is 'bin'.
34
+
35
+         Properties related to the SDK location or the project target should
36
+         be updated using the 'android' tool with the 'update' action.
37
+
38
+         This file is an integral part of the build system for your
39
+         application and should be checked into Version Control Systems.
40
+
41
+         -->
42
+    <property file="build.properties" />
43
+
44
+    <!-- The default.properties file is created and updated by the 'android'
45
+         tool, as well as ADT.
46
+         This file is an integral part of the build system for your
47
+         application and should be checked into Version Control Systems. -->
48
+    <property file="default.properties" />
49
+
50
+
51
+    <!-- Required pre-setup import -->
52
+    <import file="${sdk.dir}/tools/ant/pre_setup.xml" />
53
+
54
+
55
+<!-- extension targets. Uncomment the ones where you want to do custom work
56
+     in between standard targets -->
57
+<!--
58
+    <target name="-pre-build">
59
+    </target>
60
+    <target name="-pre-compile">
61
+    </target>
62
+
63
+    [This is typically used for code obfuscation.
64
+     Compiled code location: ${out.classes.absolute.dir}
65
+     If this is not done in place, override ${out.dex.input.absolute.dir}]
66
+    <target name="-post-compile">
67
+    </target>
68
+-->
69
+
70
+    <!-- Execute the Android Setup task that will setup some properties
71
+         specific to the target, and import the build rules files.
72
+
73
+         The rules file is imported from
74
+            <SDK>/tools/ant/
75
+         Depending on the project type it can be either:
76
+         - main_rules.xml
77
+         - lib_rules.xml
78
+         - test_rules.xml
79
+
80
+         To customize existing targets, there are two options:
81
+         - Customize only one target:
82
+             - copy/paste the target into this file, *before* the
83
+               <setup> task.
84
+             - customize it to your needs.
85
+         - Customize the whole script.
86
+             - copy/paste the content of the rules files (minus the top node)
87
+               into this file, *after* the <setup> task
88
+             - disable the import of the rules by changing the setup task
89
+               below to <setup import="false" />.
90
+             - customize to your needs.
91
+    -->
92
+    <setup />
93
+
94
+</project>

+ 11
- 0
modules/android/test_app/default.properties View File

@@ -0,0 +1,11 @@
1
+# This file is automatically generated by Android Tools.
2
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3
+#
4
+# This file must be checked in Version Control Systems.
5
+#
6
+# To customize properties used by the Ant build system use,
7
+# "build.properties", and override values to adapt the script to your
8
+# project structure.
9
+
10
+# Project target.
11
+target=android-10

+ 10
- 0
modules/android/test_app/local.properties View File

@@ -0,0 +1,10 @@
1
+# This file is automatically generated by Android Tools.
2
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3
+#
4
+# This file must *NOT* be checked in Version Control Systems,
5
+# as it contains information specific to your local configuration.
6
+
7
+# location of the SDK. This is only used by Ant
8
+# For customization when using a Version Control System, please read the
9
+# header note.
10
+sdk.dir=${user.home}/android-sdk

+ 35
- 0
modules/android/test_app/src/retrofit/test_app/Main.java View File

@@ -0,0 +1,35 @@
1
+package retrofit.test_app;
2
+
3
+import android.app.Activity;
4
+import android.os.Bundle;
5
+import android.widget.TextView;
6
+import retrofit.io.Files;
7
+
8
+import java.io.File;
9
+import java.io.IOException;
10
+
11
+public class Main extends Activity {
12
+
13
+  @Override
14
+  public void onCreate(Bundle savedInstanceState) {
15
+    super.onCreate(savedInstanceState);
16
+    TextView result = new TextView(this);
17
+
18
+    try {
19
+      File dir = getFilesDir();
20
+      Files.sync(dir);
21
+    } catch (IOException e) {
22
+      throw new AssertionError(e);
23
+    }
24
+
25
+    try {
26
+      File file = new File(getFilesDir(), "not-a-dir");
27
+      file.createNewFile();
28
+      Files.sync(file);
29
+      throw new AssertionError("Expected an IOException.");
30
+    } catch (IOException e) { /* expected */ }
31
+
32
+    result.setText("OK");
33
+    setContentView(result);
34
+  }
35
+}

+ 14
- 0
modules/android/test_app/test_app.iml View File

@@ -0,0 +1,14 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<module type="JAVA_MODULE" version="4">
3
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+    <exclude-output />
5
+    <content url="file://$MODULE_DIR$">
6
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7
+      <sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
8
+    </content>
9
+    <orderEntry type="jdk" jdkName="Android" jdkType="JavaSDK" />
10
+    <orderEntry type="sourceFolder" forTests="false" />
11
+    <orderEntry type="module" module-name="io" />
12
+  </component>
13
+</module>
14
+

+ 34
- 5
modules/io/src/retrofit/io/Files.java View File

@@ -1,7 +1,12 @@
1 1
 // Copyright 2010 Square, Inc.
2 2
 package retrofit.io;
3 3
 
4
-import java.io.*;
4
+import java.io.File;
5
+import java.io.FileInputStream;
6
+import java.io.FileOutputStream;
7
+import java.io.IOException;
8
+import java.io.InputStream;
9
+import java.io.OutputStream;
5 10
 
6 11
 /**
7 12
  * File utilities.
@@ -69,9 +74,7 @@ public class Files {
69 74
    */
70 75
   public static File build(File baseFile, String... parts) {
71 76
     File file = baseFile;
72
-    for (String part : parts) {
73
-      file = new File(file, part);
74
-    }
77
+    for (String part : parts) file = new File(file, part);
75 78
     return file;
76 79
   }
77 80
 
@@ -80,10 +83,36 @@ public class Files {
80 83
    * (that is, if the delete succeeds, or was never there in the first place).
81 84
    * A return value of <code>false</code> indicates that the delete failed.
82 85
    */
83
-  public static boolean delete(File file) throws IllegalAccessException {
86
+  public static boolean delete(File file) {
84 87
     if (file == null) {
85 88
       throw new IllegalArgumentException("Cannot delete a null file.");
86 89
     }
87 90
     return !file.exists() || file.delete();
88 91
   }
92
+
93
+  /**
94
+   * Ensures changes to the given directory have been written to storage.
95
+   * Returns after all pending changes have been written. Helps prevent
96
+   * data corruption in the event of a system crash.
97
+   *
98
+   * <p>Currently works on Android only. Support for other platforms is in the
99
+   * works.
100
+   *
101
+   * @param directory to synchronize
102
+   */
103
+  public static void sync(File directory) throws IOException {
104
+    Native.sync(directory.getPath());
105
+  }
106
+}
107
+
108
+/**
109
+ * Delays loading the native library until {@link Files#sync(java.io.File)}
110
+ * is called.
111
+ */
112
+class Native {
113
+  static {
114
+    System.loadLibrary("retrofit");
115
+  }
116
+
117
+  static native void sync(String path);
89 118
 }

+ 1
- 2
revision.properties View File

@@ -1,3 +1,2 @@
1
-# Note - with the next change, increment this to 0.6-SNAPSHOT
2
-retrofit.revision=0.5
1
+retrofit.revision=0.6-SNAPSHOT
3 2
 

Loading…
Cancel
Save