hx3d  1
2D/3D Simple Game Framework
file.cpp
1 /*
2  File handling.
3  Copyright (C) 2015 Denis BOURGE
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
21 #include "hx3d/utils/file.hpp"
22 
23 #include <SDL2/SDL_system.h>
24 #include <sstream>
25 #include <fstream>
26 
27 #include "hx3d/core/platforms.hpp"
28 #include "hx3d/utils/log.hpp"
29 
30 namespace hx3d {
31 
32 File::File():
33  data(nullptr), size(0)
34 {}
35 
36 File::~File() {
37  if (data) {
38  delete[] data;
39  }
40 }
41 
42 char* File::getData() const {
43  return data;
44 }
45 
46 size_t File::getSize() const {
47  return size;
48 }
49 
51 
52 Ptr<File> File::loadAsciiFile(std::string path) {
53  #if defined(__ANDROID__)
54  return loadAsciiFileAndroid(path);
55  #elif defined(__IOS__)
56  return loadAsciiFileiOS("assets/" + path);
57  #else
58  return loadAsciiFileDesktop("assets/" + path);
59  #endif
60 }
61 
62 Ptr<File> File::loadBinaryFile(std::string path) {
63  #if defined(__ANDROID__)
64  return loadBinaryFileAndroid(path);
65  #elif defined(__IOS__)
66  return loadBinaryFileiOS("assets/" + path);
67  #else
68  return loadBinaryFileDesktop("assets/" + path);
69  #endif
70 }
71 
73  #if defined(__ANDROID__)
74  path = getInternalPath() + "/" + path;
75  #endif
76 
77  return loadAsciiFileDesktop(path);
78 }
79 
80 void File::writeInternalAsciiFile(std::string path, std::string content) {
81  #if defined(__ANDROID__)
82  path = getInternalPath() + "/" + path;
83  #endif
84 
85  std::ofstream file(path);
86  file << content;
87  file.close();
88 }
89 
90 std::string File::toString() {
91  return std::string(data, size);
92 }
93 
94 // Desktop ///////////////////////////////////
95 
96 Ptr<File> File::loadAsciiFileDesktop(std::string path) {
97  std::ifstream file(path);
98  if (file) {
99  std::ostringstream oss("");
100  oss << file.rdbuf();
101 
102  std::string content = oss.str();
103 
104  Ptr<File> fileptr = Make<File>();
105  fileptr->size = content.size() + 1;
106  fileptr->data = new char[fileptr->size];
107  std::copy(content.begin(), content.end(), fileptr->data);
108  fileptr->data[content.size()] = '\0';
109 
110  return fileptr;
111  }
112 
113  Log.Error("Bad path: %s", path.c_str());
114 
115  return nullptr;
116 }
117 
118 Ptr<File> File::loadBinaryFileDesktop(std::string path) {
119  std::ifstream file(path, std::ios::binary);
120  if (file) {
121  Ptr<File> fileptr = Make<File>();
122  unsigned int size = 0;
123 
124  file.seekg(0, std::ios::end);
125  size = file.tellg();
126  file.seekg(0, std::ios::beg);
127 
128  fileptr->size = size;
129  fileptr->data = new char[fileptr->size];
130  file.read(fileptr->data, fileptr->size);
131  file.close();
132 
133  return fileptr;
134  }
135 
136  Log.Error("Bad path: %s", path.c_str());
137 
138  return nullptr;
139 }
140 
141 }
142 
143 // iOS ///////////////////////////////////////
144 
145 #ifdef __APPLE__
146 
147 #include "TargetConditionals.h"
148 #ifdef TARGET_OS_IPHONE
149 
150  #include <CoreFoundation/CoreFoundation.h>
151 
152 namespace hx3d {
153 
154  Ptr<File> File::loadAsciiFileiOS(std::string path) {
155  return loadAsciiFileDesktop(path);
156  }
157 
158  Ptr<File> File::loadBinaryFileiOS(std::string path) {
159  return loadBinaryFileDesktop(path);
160  }
161 }
162 
163 #endif
164 #endif
165 
166 // Android ///////////////////////////////////
167 
168 #ifdef __ANDROID__
169 
170  #include <jni.h>
171  #include <android/log.h>
172  #include <android/asset_manager.h>
173  #include <android/asset_manager_jni.h>
174 
175 namespace hx3d {
176 
177  std::string File::getInternalPath() {
178  return std::string(SDL_AndroidGetInternalStoragePath());
179  }
180 
181  std::string File::readAsString(std::string path) {
182  // Environnement et classe de l'activité
183 
184  JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
185 
186  jobject sdlActivity = (jobject)SDL_AndroidGetActivity();
187  jclass sdlActivityClass = env->GetObjectClass(sdlActivity);
188  env->DeleteLocalRef(sdlActivity);
189 
190 
191  // Méthode getContext() depuis de l'activité SDLActivity
192 
193  jmethodID getContext = env->GetStaticMethodID(sdlActivityClass, "getContext", "()Landroid/content/Context;");
194  jobject context = env->CallStaticObjectMethod(sdlActivityClass, getContext);
195 
196 
197  // Objet AssetManager de l'activité SDLActivity
198 
199  jmethodID getAssets = env->GetMethodID(env->GetObjectClass(context), "getAssets", "()Landroid/content/res/AssetManager;");
200  jobject assetManager = env->CallObjectMethod(context, getAssets);
201  AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
202 
203  if (mgr == NULL)
204  return "";
205 
206 
207  // Lecture de la ressource
208 
209  AAsset* asset = AAssetManager_open(mgr, path.c_str(), AASSET_MODE_STREAMING);
210  std::string fileContent;
211  char buffer;
212 
213 
214  // Si elle n'existe pas
215 
216  if(asset == NULL) {
217  __android_log_print(ANDROID_LOG_WARN, "SDL", "File \"%s\" does not exists", path.c_str());
218  return "";
219  }
220 
221  else {
222  // Lecture
223 
224  while (AAsset_read(asset, &buffer, 1) > 0){
225  fileContent += buffer;
226  }
227 
228  AAsset_close(asset);
229  }
230 
231  return fileContent;
232  }
233 
234  Ptr<File> File::loadBinaryFileAndroid(std::string path) {
235 
236  std::string content = File::readAsString(path);
237 
238  Ptr<File> file = Make<File>();
239  file->size = content.size();
240  file->data = new char[file->size];
241  std::copy(content.begin(), content.end(), file->data);
242 
243  return file;
244  }
245 
246  Ptr<File> File::loadAsciiFileAndroid(std::string path) {
247  std::string content = File::readAsString(path);
248 
249  Ptr<File> file = Make<File>();
250  file->size = content.size();
251  file->data = new char[file->size];
252  std::copy(content.begin(), content.end(), file->data);
253  // file->data[file->size] = '\0';
254 
255  return file;
256  }
257 }
258 
259 #endif
std::string toString()
Return the file content as a string.
Definition: file.cpp:90
char * getData() const
Get the file data as an 8-bit array.
Definition: file.cpp:42
hx3d framework namespace
Definition: audio.hpp:26
static Ptr< File > loadAsciiFile(std::string path)
Load an ascii file from a path.
Definition: file.cpp:52
static Ptr< File > loadInternalAsciiFile(std::string path)
Load an internal ascii file.
Definition: file.cpp:72
void Error(const std::string fmt,...)
Write an error message.
Definition: log.cpp:72
static hx3d::LogImpl Log
Current log implementation.
Definition: log.hpp:91
static void writeInternalAsciiFile(std::string path, std::string content)
Write to an internal ascii file.
Definition: file.cpp:80
size_t getSize() const
Get the file size.
Definition: file.cpp:46
static Ptr< File > loadBinaryFile(std::string path)
Load a binary file from a path.
Definition: file.cpp:62
std::shared_ptr< T > Ptr
Quick-typing shared ptr.
Definition: ptr.hpp:34