Imported Upstream version 0.6.3
[fdkaac.git] / src / compat_posix.c
CommitLineData
48e2f01c 1/*
2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
4 */
5#if HAVE_CONFIG_H
6# include "config.h"
7#endif
8#if HAVE_STDINT_H
9# include <stdint.h>
10#endif
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <stdarg.h>
15#include <sys/time.h>
16#include "compat.h"
17
18int64_t aacenc_timer(void)
19{
20 struct timeval tv = { 0 };
21 gettimeofday(&tv, 0);
22 return (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
23}
24
25FILE *aacenc_fopen(const char *name, const char *mode)
26{
27 FILE *fp;
28 if (strcmp(name, "-") == 0)
29 fp = (mode[0] == 'r') ? stdin : stdout;
30 else
31 fp = fopen(name, mode);
32 return fp;
33}
34
9b7e1ca6 35int aacenc_seekable(FILE *fp)
48e2f01c 36{
9b7e1ca6 37 return fseek(fp, 0, SEEK_CUR) == 0;
48e2f01c 38}
39
5888fddc 40/*
41 * Different from POSIX basename() when path ends with /.
42 * Since we use this only for a regular file, the difference doesn't matter.
43 */
44const char *aacenc_basename(const char *path)
45{
46 const char *p = strrchr(path, '/');
47 return p ? p + 1: path;
48}
49
48e2f01c 50#ifndef HAVE_ICONV
51char *aacenc_to_utf8(const char *s)
52{
53 return strdup(s);
54}
55#else /* HAVE_ICONV */
56
57#include <sys/types.h>
58#include <stddef.h>
59#include <errno.h>
60#include <iconv.h>
61
62#if HAVE_LOCALCHARSET_H
63#include <localcharset.h>
64#elif HAVE_LANGINFO_H
65#include <langinfo.h>
66static const char *locale_charset(void)
67{
68 return nl_langinfo(CODESET);
69}
70#else
71static const char *locale_charset(void)
72{
73 return 0;
74}
75#endif
76
77static
78int utf8_from_charset(const char *charset, const char *from, char **to)
79{
80 iconv_t cd;
81 size_t fromlen, obsize, ibleft, obleft;
82 char *ip, *op;
83
84 cd = iconv_open("UTF-8", charset);
85 if (cd == (iconv_t)-1)
86 return -1;
87
88 fromlen = strlen(from);
89 ibleft = fromlen;
90 obsize = 2;
91 obleft = obsize - 1;
92 *to = malloc(obsize);
93 ip = (char *)from;
94 op = *to;
95
96 while (ibleft > 0) {
97 if (iconv(cd, &ip, &ibleft, &op, &obleft) != (size_t)-1)
98 break;
99 else {
100 if (errno == E2BIG || obleft == 0) {
101 ptrdiff_t offset = op - *to;
102 obsize *= 2;
103 *to = realloc(*to, obsize);
104 op = *to + offset;
105 obleft = obsize - offset - 1;
106 }
107 if (errno == EILSEQ) {
108 ++ip;
109 --ibleft;
110 *op++ = '?';
111 --obleft;
112 }
113 if (errno != E2BIG && errno != EILSEQ)
114 break;
115 }
116 }
117 iconv_close(cd);
118 *op = 0;
119 if (fromlen > 0 && op == *to) {
120 free(op);
121 return -1;
122 }
123 return 0;
124}
125
126char *aacenc_to_utf8(const char *s)
127{
128 char *result;
129 const char *charset;
130
131 if ((charset = locale_charset()) == 0)
132 charset = "US-ASCII";
133 if (utf8_from_charset(charset, s, &result) < 0)
134 result = strdup(s);
135 return result;
136}
137#endif /* HAVE_ICONV */
This page took 0.017617 seconds and 4 git commands to generate.