1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 //
5 // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // https://opensource.org/licenses/BSD-3-Clause
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #include "datareader.h"
16 
17 #include <string.h>
18 
19 namespace ncnn {
20 
DataReader()21 DataReader::DataReader()
22 {
23 }
24 
~DataReader()25 DataReader::~DataReader()
26 {
27 }
28 
29 #if NCNN_STRING
scan(const char *,void *) const30 int DataReader::scan(const char* /*format*/, void* /*p*/) const
31 {
32     return 0;
33 }
34 #endif // NCNN_STRING
35 
read(void *,size_t) const36 size_t DataReader::read(void* /*buf*/, size_t /*size*/) const
37 {
38     return 0;
39 }
40 
41 #if NCNN_STDIO
42 class DataReaderFromStdioPrivate
43 {
44 public:
DataReaderFromStdioPrivate(FILE * _fp)45     DataReaderFromStdioPrivate(FILE* _fp)
46         : fp(_fp)
47     {
48     }
49     FILE* fp;
50 };
51 
DataReaderFromStdio(FILE * _fp)52 DataReaderFromStdio::DataReaderFromStdio(FILE* _fp)
53     : DataReader(), d(new DataReaderFromStdioPrivate(_fp))
54 {
55 }
56 
~DataReaderFromStdio()57 DataReaderFromStdio::~DataReaderFromStdio()
58 {
59     delete d;
60 }
61 
DataReaderFromStdio(const DataReaderFromStdio &)62 DataReaderFromStdio::DataReaderFromStdio(const DataReaderFromStdio&)
63     : d(0)
64 {
65 }
66 
operator =(const DataReaderFromStdio &)67 DataReaderFromStdio& DataReaderFromStdio::operator=(const DataReaderFromStdio&)
68 {
69     return *this;
70 }
71 
72 #if NCNN_STRING
scan(const char * format,void * p) const73 int DataReaderFromStdio::scan(const char* format, void* p) const
74 {
75     return fscanf(d->fp, format, p);
76 }
77 #endif // NCNN_STRING
78 
read(void * buf,size_t size) const79 size_t DataReaderFromStdio::read(void* buf, size_t size) const
80 {
81     return fread(buf, 1, size, d->fp);
82 }
83 #endif // NCNN_STDIO
84 
85 class DataReaderFromMemoryPrivate
86 {
87 public:
DataReaderFromMemoryPrivate(const unsigned char * & _mem)88     DataReaderFromMemoryPrivate(const unsigned char*& _mem)
89         : mem(_mem)
90     {
91     }
92     const unsigned char*& mem;
93 };
94 
DataReaderFromMemory(const unsigned char * & _mem)95 DataReaderFromMemory::DataReaderFromMemory(const unsigned char*& _mem)
96     : DataReader(), d(new DataReaderFromMemoryPrivate(_mem))
97 {
98 }
99 
~DataReaderFromMemory()100 DataReaderFromMemory::~DataReaderFromMemory()
101 {
102     delete d;
103 }
104 
DataReaderFromMemory(const DataReaderFromMemory &)105 DataReaderFromMemory::DataReaderFromMemory(const DataReaderFromMemory&)
106     : d(0)
107 {
108 }
109 
operator =(const DataReaderFromMemory &)110 DataReaderFromMemory& DataReaderFromMemory::operator=(const DataReaderFromMemory&)
111 {
112     return *this;
113 }
114 
115 #if NCNN_STRING
scan(const char * format,void * p) const116 int DataReaderFromMemory::scan(const char* format, void* p) const
117 {
118     size_t fmtlen = strlen(format);
119 
120     char* format_with_n = new char[fmtlen + 4];
121     sprintf(format_with_n, "%s%%n", format);
122 
123     int nconsumed = 0;
124     int nscan = sscanf((const char*)d->mem, format_with_n, p, &nconsumed);
125     d->mem += nconsumed;
126 
127     delete[] format_with_n;
128 
129     return nconsumed > 0 ? nscan : 0;
130 }
131 #endif // NCNN_STRING
132 
read(void * buf,size_t size) const133 size_t DataReaderFromMemory::read(void* buf, size_t size) const
134 {
135     memcpy(buf, d->mem, size);
136     d->mem += size;
137     return size;
138 }
139 
140 #if NCNN_PLATFORM_API
141 #if __ANDROID_API__ >= 9
142 class DataReaderFromAndroidAssetPrivate
143 {
144 public:
DataReaderFromAndroidAssetPrivate(AAsset * _asset)145     DataReaderFromAndroidAssetPrivate(AAsset* _asset)
146         : asset(_asset), mem(0)
147     {
148     }
149     AAsset* asset;
150     mutable const unsigned char* mem;
151 };
152 
DataReaderFromAndroidAsset(AAsset * _asset)153 DataReaderFromAndroidAsset::DataReaderFromAndroidAsset(AAsset* _asset)
154     : DataReader(), d(new DataReaderFromAndroidAssetPrivate(_asset))
155 {
156 }
157 
~DataReaderFromAndroidAsset()158 DataReaderFromAndroidAsset::~DataReaderFromAndroidAsset()
159 {
160     delete d;
161 }
162 
DataReaderFromAndroidAsset(const DataReaderFromAndroidAsset &)163 DataReaderFromAndroidAsset::DataReaderFromAndroidAsset(const DataReaderFromAndroidAsset&)
164     : d(0)
165 {
166 }
167 
operator =(const DataReaderFromAndroidAsset &)168 DataReaderFromAndroidAsset& DataReaderFromAndroidAsset::operator=(const DataReaderFromAndroidAsset&)
169 {
170     return *this;
171 }
172 
173 #if NCNN_STRING
scan(const char * format,void * p) const174 int DataReaderFromAndroidAsset::scan(const char* format, void* p) const
175 {
176     if (!d->mem)
177     {
178         off_t pos = AAsset_seek(d->asset, 0, SEEK_CUR);
179         d->mem = (const unsigned char*)AAsset_getBuffer(d->asset);
180         d->mem += pos;
181     }
182 
183     int fmtlen = strlen(format);
184 
185     char* format_with_n = new char[fmtlen + 3];
186     sprintf(format_with_n, "%s%%n", format);
187 
188     int nconsumed = 0;
189     int nscan = sscanf((const char*)d->mem, format_with_n, p, &nconsumed);
190     d->mem += nconsumed;
191 
192     delete[] format_with_n;
193 
194     if (nconsumed == 0)
195         return 0;
196 
197     AAsset_seek(d->asset, nconsumed, SEEK_CUR);
198 
199     return nscan;
200 }
201 #endif // NCNN_STRING
202 
read(void * buf,size_t size) const203 size_t DataReaderFromAndroidAsset::read(void* buf, size_t size) const
204 {
205     int nread = AAsset_read(d->asset, buf, size);
206     if (nread < 0)
207         return 0;
208 
209     if (d->mem)
210     {
211         d->mem += nread;
212     }
213 
214     return nread;
215 }
216 #endif // __ANDROID_API__ >= 9
217 #endif // NCNN_PLATFORM_API
218 
219 } // namespace ncnn
220