51tld_file_error tld_file_load_stream(
tld_file ** file, std::istream & in)
54 in.read(
reinterpret_cast<char *
>(&magic),
sizeof(magic));
56 || in.gcount() !=
sizeof(magic))
58 return TLD_FILE_ERROR_CANNOT_READ_FILE;
61 if(magic.f_riff != TLD_MAGIC
62 || magic.f_type != TLD_TLDS)
64 return TLD_FILE_ERROR_UNRECOGNIZED_FILE;
67 || magic.f_size > 1024 * 1024)
69 return TLD_FILE_ERROR_INVALID_FILE_SIZE;
71 uint32_t size(magic.f_size -
sizeof(uint32_t));
79 return TLD_FILE_ERROR_OUT_OF_MEMORY;
90 auto_free(auto_free
const &) =
delete;
102 auto_free & operator = (auto_free
const &) =
delete;
112 auto_free safe_ptr(file);
118 in.read(
reinterpret_cast<char *
>(hunk), size);
120 || in.gcount() != size)
122 return TLD_FILE_ERROR_CANNOT_READ_FILE;
129 return TLD_FILE_ERROR_INVALID_HUNK_SIZE;
133 if(hunk->f_size > size)
135 return TLD_FILE_ERROR_INVALID_HUNK_SIZE;
137 size -= hunk->f_size;
144 return TLD_FILE_ERROR_INVALID_STRUCTURE_SIZE;
146 if((*file)->f_header !=
nullptr)
148 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
150 (*file)->f_header =
reinterpret_cast<tld_header *
>(hunk + 1);
151 if((*file)->f_header->f_version_major != TLD_FILE_VERSION_MAJOR
152 || (*file)->f_header->f_version_minor != TLD_FILE_VERSION_MINOR)
154 return TLD_FILE_ERROR_UNSUPPORTED_VERSION;
158 case TLD_DESCRIPTIONS:
159 (*file)->f_descriptions_count = hunk->f_size /
sizeof(
tld_description);
160 if((*file)->f_descriptions_count *
sizeof(
tld_description) != hunk->f_size)
162 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
164 if((*file)->f_descriptions !=
nullptr)
166 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
168 (*file)->f_descriptions =
reinterpret_cast<tld_description *
>(hunk + 1);
176 (*file)->f_tags_size = hunk->f_size /
sizeof(uint32_t);
177 if((*file)->f_tags_size *
sizeof(uint32_t) != hunk->f_size)
179 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
181 if((*file)->f_tags !=
nullptr)
183 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
185 (*file)->f_tags =
reinterpret_cast<uint32_t *
>(hunk + 1);
188 case TLD_STRING_OFFSETS:
189 if((*file)->f_strings_count == 0)
192 if((*file)->f_strings_count == 0)
194 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
199 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
201 if((*file)->f_string_offsets !=
nullptr)
203 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
208 case TLD_STRING_LENGTHS:
209 if((*file)->f_strings_count == 0)
212 if((*file)->f_strings_count == 0)
214 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
219 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
221 if((*file)->f_string_lengths !=
nullptr)
223 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
229 if(hunk->f_size == 0)
231 return TLD_FILE_ERROR_INVALID_ARRAY_SIZE;
233 if((*file)->f_strings !=
nullptr)
235 return TLD_FILE_ERROR_HUNK_FOUND_TWICE;
237 (*file)->f_strings =
reinterpret_cast<char *
>(hunk + 1);
238 (*file)->f_strings_end =
reinterpret_cast<char *
>(hunk + 1) + hunk->f_size;
247 hunk =
reinterpret_cast<tld_hunk *
>(
reinterpret_cast<char *
>(hunk + 1) + hunk->f_size);
252 if((*file)->f_header ==
nullptr
253 || (*file)->f_descriptions ==
nullptr
254 || (*file)->f_tags ==
nullptr
255 || (*file)->f_string_offsets ==
nullptr
256 || (*file)->f_string_lengths ==
nullptr
257 || (*file)->f_strings ==
nullptr)
259 return TLD_FILE_ERROR_MISSING_HUNK;
266 return TLD_FILE_ERROR_NONE;
275enum tld_file_error tld_file_load(
char const * filename,
tld_file ** file)
278 || filename ==
nullptr)
280 return TLD_FILE_ERROR_INVALID_POINTER;
284 return TLD_FILE_ERROR_POINTER_PRESENT;
291 return TLD_FILE_ERROR_CANNOT_OPEN_FILE;
294 return tld_file_load_stream(file, in);
298const char *tld_file_errstr(tld_file_error err)
302 case TLD_FILE_ERROR_NONE:
305 case TLD_FILE_ERROR_INVALID_POINTER:
306 return "Invalid pointer";
308 case TLD_FILE_ERROR_POINTER_PRESENT:
309 return "Pointer present when it should ne nullptr";
311 case TLD_FILE_ERROR_CANNOT_OPEN_FILE:
312 return "Cannot open file";
314 case TLD_FILE_ERROR_CANNOT_READ_FILE:
315 return "I/O error reading file";
317 case TLD_FILE_ERROR_UNRECOGNIZED_FILE:
318 return "Unrecognized input file";
320 case TLD_FILE_ERROR_INVALID_FILE_SIZE:
321 return "Invalid file size";
323 case TLD_FILE_ERROR_OUT_OF_MEMORY:
324 return "Out of memory";
326 case TLD_FILE_ERROR_INVALID_HUNK_SIZE:
327 return "Invalid hunk size";
329 case TLD_FILE_ERROR_INVALID_STRUCTURE_SIZE:
330 return "Invalid structure size";
332 case TLD_FILE_ERROR_INVALID_ARRAY_SIZE:
333 return "Invalid array size";
335 case TLD_FILE_ERROR_UNSUPPORTED_VERSION:
336 return "Unsupported version";
338 case TLD_FILE_ERROR_MISSING_HUNK:
339 return "Missing hunk";
341 case TLD_FILE_ERROR_HUNK_FOUND_TWICE:
342 return "Found the same hunk twice";
348 return "Unknown tld_file error number";
354 if(
id >= file->f_descriptions_count)
358 return file->f_descriptions + id;
364 if(
id + 1 >= file->f_tags_size)
368 return reinterpret_cast<tld_tag *
>(file->f_tags + id);
372char const * tld_file_string(
tld_file const * file, uint32_t
id, uint32_t * length)
374 if(length ==
nullptr)
382 if(
id >= file->f_strings_count)
387 char const * s(file->f_strings + file->f_string_offsets[
id].f_string_offset);
388 uint32_t l(file->f_string_lengths[
id].f_string_length);
389 char const * e(s + l);
390 if(s > file->f_strings_end
391 || e > file->f_strings_end)
417 || file->f_header ==
nullptr
418 || file->f_descriptions ==
nullptr
419 || file->f_tags ==
nullptr
420 || file->f_string_offsets ==
nullptr
421 || file->f_string_lengths ==
nullptr
422 || file->f_strings ==
nullptr)
427 std::stringstream out;
430 out <<
"\"version\":\"" <<
static_cast<int>(file->f_header->f_version_major)
431 <<
'.' <<
static_cast<int>(file->f_header->f_version_minor) <<
"\",\n";
432 out <<
"\"created-on\":" << file->f_header->f_created_on <<
",\n";
433 out <<
"\"max-level\":" <<
static_cast<int>(file->f_header->f_tld_max_level) <<
",\n";
434 out <<
"\"tld-start-offset\":" <<
static_cast<int>(file->f_header->f_tld_start_offset) <<
",\n";
435 out <<
"\"tld-end-offset\":" <<
static_cast<int>(file->f_header->f_tld_end_offset) <<
",\n";
436 out <<
"\"descriptions\":[\n";
437 for(uint32_t idx(0); idx < file->f_descriptions_count; ++idx)
441 out << (idx == 0 ?
"" :
",\n");
445 char const *
tld(tld_file_string(file, d->
f_tld, &length));
446 out <<
"{\"tld\":\"" << std::string(
tld, length) <<
"\"";
455 char const * to_tld(tld_file_string(file, apply_to->
f_tld, &length));
456 out <<
",\"apply-to\":\"" << std::string(to_tld, length) <<
"\"";
467 const tld_tag * tag(tld_file_tag(file, d->
f_tags + tidx * 2));
470 char const * tag_name(tld_file_string(file, tag->f_tag_name, &length));
471 out <<
",\"" << std::string(tag_name, length)
476 char const * tag_value(tld_file_string(file, tag->f_tag_value, &length));
477 out << std::string(tag_value, length)
486 return strdup(out.str().c_str());
[internal] The description of one TLD.
uint16_t f_end_offset
The last offset of a list of TLDs.
uint16_t f_tags_count
The number of tags defined by this TLD.
uint16_t f_start_offset
The first offset of a list of TLDs.
uint16_t f_tld
The actual TLD of this entry.
uint16_t f_exception_apply_to
This TLD is an exception of the "apply to" TLD.
uint16_t f_tags
The tags of this TLD.
uint8_t f_status
The status of this TLD.
The public header of the libtld library.
LIBTLD_EXPORT enum tld_result tld(const char *uri, struct tld_info *info)
Get information about the TLD for the specified URI.
LIBTLD_EXPORT const char * tld_status_to_string(enum tld_status status)
Transform the status to a string.
Declaration of the static TLDs file.
char * tld_file_to_json(tld_file const *file)
Transform a tld_file to a JSON string.
Declaration of the TLD file structures.