Importing lz4json from https://github.com/andikleen/lz4json
[lz4json.git] / lz4jsoncat.c
1 /* 
2  * Dump mozilla style lz4json files.
3  *
4  * Copyright (c) 2014 Intel Corporation
5  * Author: Andi Kleen
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution
13  *
14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18
19 /* File format reference:
20    http://mxr.mozilla.org/mozilla-central/source/toolkit/components/workerlz4/lz4.js 
21  */
22 #include <sys/mman.h>
23 #include <sys/stat.h>
24 #include <sys/fcntl.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30
31 #include "lz4.h"
32
33 /* Assumes little endian host for the length */
34
35 int main(int ac, char **av)
36 {
37         while (*++av) {
38                 int fd = open(*av, O_RDONLY);
39                 if (fd < 0) {
40                         perror(*av);
41                         continue;
42                 }
43                 struct stat st;
44                 if (fstat(fd, &st) < 0) {
45                         perror(*av);
46                         exit(1);
47                 }
48                 if (st.st_size < 12) {
49                         fprintf(stderr, "%s: file too short\n", *av);
50                         exit(1);
51                 }
52
53                 unsigned ps = sysconf(_SC_PAGE_SIZE);
54                 char *map = mmap(NULL, (st.st_size + ps - 1) & ~(ps - 1), PROT_READ,
55                                  MAP_SHARED, fd, 0);
56                 if (map == (char *)-1) {
57                         perror(*av);
58                         exit(1);
59                 }
60                 if (memcmp(map, "mozLz40", 8)) {
61                         fprintf(stderr, "%s: not a mozLZ4a file\n", *av);
62                         exit(1);
63                 }
64                 size_t outsz = *(uint32_t *) (map + 8);
65                 char *out = malloc(outsz);
66                 if (!out) {
67                         fprintf(stderr, "Cannot allocate memory\n");
68                         exit(1);
69                 }
70                 if (LZ4_decompress_safe_partial(map + 12, out, st.st_size - 12, outsz, outsz) < 0) {
71                         fprintf(stderr, "%s: decompression error\n", *av);
72                         exit(1);
73                 }
74                 if (write(1, out, outsz) < outsz) {
75                         perror("write");
76                         exit(1);
77                 }
78                 free(out);
79                 munmap(map, (st.st_size + ps - 1) & ~(ps - 1));
80                 close(fd);
81
82         }
83         return 0;
84 }
85
86
87