2 * lmo - Lua Machine Objects - Base functions
4 * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 extern char _lmo_error[1024];
23 static int lmo_read32( int fd, uint32_t *val )
25 if( read(fd, val, 4) < 4 )
33 static char * error(const char *message, int add_errno)
35 memset(_lmo_error, 0, sizeof(_lmo_error));
38 snprintf(_lmo_error, sizeof(_lmo_error),
39 "%s: %s", message, strerror(errno));
41 snprintf(_lmo_error, sizeof(_lmo_error), "%s", message);
46 const char * lmo_error(void)
51 lmo_archive_t * lmo_open(const char *file)
54 uint32_t idx_offset = 0;
58 lmo_archive_t *ar = NULL;
59 lmo_entry_t *head = NULL;
60 lmo_entry_t *entry = NULL;
62 if( stat(file, &s) == -1 )
64 error("Can not stat file", 1);
68 if( (in = open(file, O_RDONLY)) == -1 )
70 error("Can not open file", 1);
74 if( lseek(in, -sizeof(uint32_t), SEEK_END) == -1 )
76 error("Can not seek to eof", 1);
80 if( lmo_read32(in, &idx_offset) != 4 )
82 error("Unexpected EOF while reading index offset", 0);
86 if( lseek(in, (off_t)idx_offset, SEEK_SET) == -1 )
88 error("Can not seek to index offset", 1);
92 if( (ar = (lmo_archive_t *) malloc(sizeof(lmo_archive_t))) != NULL )
95 ar->length = idx_offset;
98 i < (s.st_size - sizeof(uint32_t));
99 i += (4 * sizeof(uint32_t))
101 if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL )
103 if( (lmo_read32(ar->fd, &entry->key_id) == 4) &&
104 (lmo_read32(ar->fd, &entry->val_id) == 4) &&
105 (lmo_read32(ar->fd, &entry->offset) == 4) &&
106 (lmo_read32(ar->fd, &entry->length) == 4)
113 error("Unexpected EOF while reading index entry", 0);
119 error("Out of memory", 0);
126 if( lseek(ar->fd, 0, SEEK_SET) == -1 )
128 error("Can not seek to start", 1);
132 if( (ar->mmap = mmap(NULL, ar->length, PROT_READ, MAP_PRIVATE, ar->fd, 0)) == MAP_FAILED )
134 error("Failed to memory map archive contents", 1);
142 error("Out of memory", 0);
156 while( entry != NULL )
168 if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) )
169 munmap(ar->mmap, ar->length);
178 void lmo_close(lmo_archive_t *ar)
180 lmo_entry_t *head = NULL;
181 lmo_entry_t *entry = NULL;
187 while( entry != NULL )
196 if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) )
197 munmap(ar->mmap, ar->length);
206 int lmo_lookup(lmo_archive_t *ar, const char *key, char *dest, int len)
208 uint32_t look_key = sfh_hash(key, strlen(key));
217 while( entry != NULL )
219 if( entry->key_id == look_key )
221 copy_len = (len > entry->length) ? entry->length : len;
222 memcpy(dest, &ar->mmap[entry->offset], copy_len);