source: trunk/lib/lang/lang.c @ 1234

Revision 1234, 4.4 KB checked in by reyalp, 23 months ago (diff)

memory saving patch from philmoz in http://chdk.setepontos.com/index.php?topic=650.msg70056#msg70056

  • changed some struct values from int to short (conf.c, gui_menu.h, platform.h)
  • gui code cleanup plus some helper functions in gui_draw
  • changed palette display under Miscellaneous stuff menu to use the same UI as the color picker in Visual settings (better and consistent UI, plus removes a chunk of code)
  • packed version of font_8x16_uni.h default font, plus new tool to create packed version (this is done during the build so if changes are need to the font they can be done in font_8x16_uni.h).
  • Change 'strings' pointer table in lang.c to an offset table (halves table size).
  • Changes lang.c to use one buffer for the strings instead of allocating a new buffer for each string,
  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "lang.h"
3
4//-------------------------------------------------------------------
5
6// Array of offsets to each string stored in the 'sbuf' array
7static unsigned short *strings = NULL;
8static int count = 0;
9
10// Strings stored in one large umalloc'ed array rather than individually (reduces memory overhead)
11// Previously when loading a language file a block of memory was allocated to read the file
12// then another block was allocated for each string in the data read from the file, then the original
13// block was freed. This version uses the same buffer to read the file and store the strings.
14static char *sbuf = NULL;   
15static int sbuflen = 0;
16
17//-------------------------------------------------------------------
18void lang_init(int num) {
19    int i;
20
21    // Free old buffer (should not happen since this is only called once at startup)
22    if (strings)
23    {
24       ufree(strings);
25       strings = 0;
26       count = 0;
27    }
28
29    // Free old buffer (should not happen since this is only called once at startup)
30    if (sbuf)
31    {
32        ufree(sbuf);
33        sbuf = 0;
34        sbuflen = 0;
35    }
36
37    // Allocate offset buffer
38    ++num;
39    strings = umalloc(num*sizeof(unsigned short));
40    if (strings) {
41        memset(strings, 0, num*sizeof(unsigned short));
42        count = num;
43    }
44}
45
46//-------------------------------------------------------------------
47// Add a string to the buffer. String is cleaned up to convert special
48// characters and the offset of the string in 'sbuf' is stored in the
49// strings array.
50static void lang_add_string(int num, char *str) {
51    int f=0;
52    char *p;
53
54    if (num<count) {
55       p = str;
56       strings[num] = (unsigned short)(str - sbuf);
57       if (p) {
58           for (; *str; ++str) {
59                if (f) {
60                    if (*str == '"' || *str == '\\') *(p-1)=*str;
61                    else if (*str == 'n') *(p-1)='\n';
62                    else *p++=*str;
63                    f = 0;
64                } else {
65                    *p++=*str;
66                    if (*str == '\\') {
67                        f = 1;
68                    }
69                }
70           }
71           *p=0;
72       }
73    }
74}
75
76//-------------------------------------------------------------------
77// Parse the 'sbuf' memory and build the strings offset array
78void lang_load_from_sbuf()
79{
80    char *p, *s, *e;
81    int i;
82   
83    e = sbuf-1;
84    while(e) {
85        p = e+1;
86        while (*p && (*p=='\r' || *p=='\n')) ++p;
87        i = strtol(p, &e, 0);
88        if (e!=p) {
89            p = e;
90            e = strpbrk(p, "\r\n");
91            if (e) *e=0;
92            while (*p && *p!='\"') ++p;
93            if (*p) ++p;
94            s = p;
95            while (*p && (*p!='\"' || *(p-1)=='\\')) ++p;
96            *p=0;
97            lang_add_string(i, s);
98        } else { //skip invalid line
99            e = strpbrk(p, "\r\n");
100            if (e) *e=0;
101        }
102    }
103}
104
105//-------------------------------------------------------------------
106// Allocate a new 'sbuf' array if needed.
107// If the existing one is large enough use it instead of getting a new block of memory.
108int alloc_sbuf(int len)
109{
110    if (len > sbuflen)
111    {
112        if (sbuf) ufree(sbuf);
113        sbuf = umalloc(len);
114        if (sbuf)
115        {
116            sbuflen = len;
117        }
118    }
119    return (sbuf != 0);
120}
121//-------------------------------------------------------------------
122// Load the default language data from memory.
123void lang_load_from_mem(char *buf) {
124    if (alloc_sbuf(strlen(buf)+1))
125    {
126        memcpy(sbuf,buf,sbuflen);
127        lang_load_from_sbuf();
128    }
129}
130
131//-------------------------------------------------------------------
132// Load language data from a file.
133void lang_load_from_file(const char *filename) {
134    int f, size;
135    static struct stat st;
136    char *buf;
137
138    f = open(filename, O_RDONLY, 0777);
139    if (f>=0) {
140        size = (stat((char*)filename, &st)==0)?st.st_size:0;
141        if (size) {
142            if (alloc_sbuf(size+1))
143            {
144                size = read(f, sbuf, size);
145                sbuf[size]=0;
146                lang_load_from_sbuf();
147            }
148        }
149        close(f);
150    }
151}
152
153//-------------------------------------------------------------------
154// Return the string corresponding to the 'str' index.
155char* lang_str(int str) {
156    if (str && str<0x1000) {
157        return (strings && str<count && strings[str])?sbuf+strings[str]:"";
158    } else { // not ID, just char*
159        return (char*)str;
160    }
161}
Note: See TracBrowser for help on using the repository browser.