1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.support.text.emoji;
18 
19 import android.content.Context;
20 import android.util.Log;
21 
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 class EmojiRepo {
30     private static final String TAG = "EmojiData";
31     private static List<EmojiData> sEmojis = new ArrayList<>();
32 
EmojiRepo()33     private EmojiRepo() {
34     }
35 
getEmojis()36     static List<EmojiData> getEmojis() {
37         return sEmojis;
38     }
39 
load(final Context context)40     static synchronized void load(final Context context) {
41         new Thread(() -> {
42             try {
43                 read(context);
44             } catch (Throwable t) {
45                 Log.e(TAG, "Cannot load emojis", t);
46             }
47         }).start();
48     }
49 
read(Context context)50     private static void read(Context context) throws IOException {
51         final InputStream inputStream = context.getAssets().open("emojis.txt");
52         try {
53             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
54             final StringBuilder stringBuilder = new StringBuilder();
55             final StringBuilder codepointBuilder = new StringBuilder();
56             List<Integer> codepointsList;
57 
58             String s;
59             while ((s = reader.readLine()) != null) {
60                 s = s.trim();
61                 // skip comments
62                 if (s.isEmpty() || s.startsWith("#")) continue;
63 
64                 stringBuilder.setLength(0);
65                 codepointBuilder.setLength(0);
66                 codepointsList = new ArrayList<>();
67 
68                 // emoji codepoints are space separated: i.e. 0x1f1e6 0x1f1e8
69                 final String[] split = s.split(" ", -1);
70 
71                 for (int index = 0; index < split.length; index++) {
72                     final String part = split[index].trim();
73                     int codepoint = Integer.parseInt(part, 16);
74                     codepointsList.add(codepoint);
75                     codepointBuilder.append(String.format("u+%04x", codepoint));
76                     codepointBuilder.append(" ");
77                     stringBuilder.append(Character.toChars(codepoint));
78                 }
79                 final EmojiData emojiData = new EmojiData(stringBuilder.toString(), codepointsList,
80                         codepointBuilder.toString());
81                 sEmojis.add(emojiData);
82             }
83         } finally {
84             inputStream.close();
85         }
86     }
87 
88     static class EmojiData {
89         private String mEmoji;
90         private List<Integer> mCodepoints;
91         private String mCodepointString;
92 
EmojiData(String emoji, List<Integer> codepoints, String codepointString)93         EmojiData(String emoji, List<Integer> codepoints, String codepointString) {
94             mEmoji = emoji;
95             mCodepoints = codepoints;
96             mCodepointString = codepointString;
97         }
98 
getEmoji()99         public String getEmoji() {
100             return mEmoji;
101         }
102 
getCodepoints()103         public List<Integer> getCodepoints() {
104             return mCodepoints;
105         }
106 
getCodepointString()107         public String getCodepointString() {
108             return mCodepointString;
109         }
110     }
111 }
112