rename `NativeString` to `CString`
[nit.git] / lib / mnit / android / android_assets.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Implements the `mnit::assets` services with a wraper around the filesystem
18 # API provided by the Android ndk.
19 #
20 # This module relies heavily on 3 C libraries:
21 # * The Android ndk
22 # * zlib (which is included in the Android ndk)
23 # * libpng which must be provided by the Nit compilation framework
24 module android_assets
25
26 import mnit
27 import android_app
28 intrude import android::assets_and_resources
29 intrude import android::load_image
30
31 extern class AndroidAsset in "C" `{struct AAsset*`}
32
33 fun read(count: Int): nullable String import String.as nullable, CString.to_s `{
34 char *buffer = malloc(sizeof(char) * (count+1));
35 int read = AAsset_read(self, buffer, count);
36 if (read != count)
37 return null_String();
38 else
39 {
40 buffer[count] = '\0';
41 return String_as_nullable(CString_to_s(buffer));
42 }
43 `}
44
45 fun length: Int `{
46 return AAsset_getLength(self);
47 `}
48
49 fun to_fd: Int `{
50 off_t start;
51 off_t length;
52 int fd = AAsset_openFileDescriptor(self, &start, &length);
53 return fd;
54 `}
55
56 fun close `{
57 AAsset_close(self);
58 `}
59 end
60
61 redef class App
62 redef fun try_loading_asset(path)
63 do
64 # Load images with the Java API
65 var ext = path.file_extension
66 if ext == "png" or ext == "jpg" or ext == "jpeg" then
67 jni_env.push_local_frame 4
68
69 var bmp = asset_manager.bitmap(path)
70 var buf = bmp.copy_pixels(true, true)
71 var w2 = bmp.width.next_pow(2)
72 var h2 = bmp.height.next_pow(2)
73 var png = new Opengles1Image.from_data(buf.native_array, bmp.width, bmp.height, w2, h2, true)
74
75 buf.destroy
76 jni_env.pop_local_frame
77 return png
78 end
79
80 var a = load_asset_from_apk(path)
81 if a != null then
82 if ext == "txt" then
83 var len = a.length
84 var txt = a.read(len)
85 return txt
86 end
87 else
88 print "didn't get asset {path}"
89 end
90
91 return null
92 end
93
94 protected fun load_asset_from_apk(path: String): nullable AndroidAsset import String.to_cstring, AndroidAsset.as nullable, native_app_glue `{
95 struct android_app *native_app_glue = App_native_app_glue(self);
96 struct AAsset* a = AAssetManager_open(native_app_glue->activity->assetManager, String_to_cstring(path), AASSET_MODE_BUFFER);
97 if (a == NULL)
98 {
99 LOGW("nit d g a");
100 return null_AndroidAsset();
101 }
102 else
103 {
104 return AndroidAsset_as_nullable(a);
105 }
106 `}
107 end
108
109 redef class Opengles1Image
110 private new from_data(pixels: Pointer, width, height, width_pow2, height_pow2: Int, has_alpha: Bool) `{
111 return mnit_opengles_load_image((const uint_least32_t *)pixels,
112 width, height, width_pow2, height_pow2, has_alpha);
113 `}
114 end