Are there simple examples of how to parse a simple JSON file using the C-based YAJL library? - iphone

I know there is an Objective-C wrapper around YAJL, but this is a really fat thing which blows up the whole JASON parser to a ridiculous huge amount of 21 files, many of them with tiny scroll bars.
So to keep my app binary small I'd like to stick with the C-version of that parser. But I'm having a hard time finding any useful documentation for this rather than the wrapper.
Maybe someone who used the C-base can point out such a tutorial or documentation?

The documentation with C examples can be found here: http://lloyd.github.com/yajl/
The github repository with examples can be found here : https://github.com/lloyd/yajl
Here is a C example that reformats JSON from stdin:
#include <yajl/yajl_parse.h>
#include <yajl/yajl_gen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int reformat_null(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_null(g);
}
static int reformat_boolean(void * ctx, int boolean)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_bool(g, boolean);
}
static int reformat_number(void * ctx, const char * s, size_t l)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_number(g, s, l);
}
static int reformat_string(void * ctx, const unsigned char * stringVal,
size_t stringLen)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}
static int reformat_map_key(void * ctx, const unsigned char * stringVal,
size_t stringLen)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}
static int reformat_start_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_map_open(g);
}
static int reformat_end_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_map_close(g);
}
static int reformat_start_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_array_open(g);
}
static int reformat_end_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
return yajl_gen_status_ok == yajl_gen_array_close(g);
}
static yajl_callbacks callbacks = {
reformat_null,
reformat_boolean,
NULL,
NULL,
reformat_number,
reformat_string,
reformat_start_map,
reformat_map_key,
reformat_end_map,
reformat_start_array,
reformat_end_array
};
static void
usage(const char * progname)
{
fprintf(stderr, "%s: reformat json from stdin\n"
"usage: json_reformat [options]\n"
" -m minimize json rather than beautify (default)\n"
" -u allow invalid UTF8 inside strings during parsing\n",
progname);
exit(1);
}
int
main(int argc, char ** argv)
{
yajl_handle hand;
static unsigned char fileData[65536];
/* generator config */
yajl_gen g;
yajl_status stat;
size_t rd;
int retval = 0;
int a = 1;
g = yajl_gen_alloc(NULL);
yajl_gen_config(g, yajl_gen_beautify, 1);
yajl_gen_config(g, yajl_gen_validate_utf8, 1);
/* ok. open file. let's read and parse */
hand = yajl_alloc(&callbacks, NULL, (void *) g);
/* and let's allow comments by default */
yajl_config(hand, yajl_allow_comments, 1);
/* check arguments.*/
while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
unsigned int i;
for ( i=1; i < strlen(argv[a]); i++) {
switch (argv[a][i]) {
case 'm':
yajl_gen_config(g, yajl_gen_beautify, 0);
break;
case 'u':
yajl_config(hand, yajl_dont_validate_strings, 1);
break;
default:
fprintf(stderr, "unrecognized option: '%c'\n\n",
argv[a][i]);
usage(argv[0]);
}
}
++a;
}
if (a < argc) {
usage(argv[0]);
}
for (;;) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
if (rd == 0) {
if (!feof(stdin)) {
fprintf(stderr, "error on file read.\n");
retval = 1;
}
break;
}
fileData[rd] = 0;
stat = yajl_parse(hand, fileData, rd);
if (stat != yajl_status_ok) break;
{
const unsigned char * buf;
size_t len;
yajl_gen_get_buf(g, &buf, &len);
fwrite(buf, 1, len, stdout);
yajl_gen_clear(g);
}
}
stat = yajl_complete_parse(hand);
if (stat != yajl_status_ok) {
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, "%s", (const char *) str);
yajl_free_error(hand, str);
retval = 1;
}
yajl_gen_free(g);
yajl_free(hand);
return retval;
}

Related

WL_SHM_FORMAT_ARGB8888 not fully transparent if color bit was set

I am learning Wayland client programming and now I'm trying to make transparent surface.
I created a buffer and paint each pixels to shared memory. I am using WL_SHM_FORMAT_ARGB8888 format but it is not working as I expected.
As I understand, 0x00ff0000 means 255 red, 0 green, 0 blue and 0 alpha so the pixel should not shown. But it shows semi-transparent red surface to me.
Below is entire source code working on Weston compositor.
// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include "xdg-shell.h"
struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct wl_surface *surface;
struct zxdg_shell_v6 *xdg_shell = NULL;
struct zxdg_surface_v6 *xdg_surface;
struct zxdg_toplevel_v6 *xdg_toplevel;
struct wl_shm *shm;
struct wl_buffer *buffer;
void *shm_data;
int WIDTH = 480;
int HEIGHT = 360;
//===============
// Xdg
//===============
static void xdg_shell_ping_handler(void *data, struct zxdg_shell_v6 *xdg_shell,
uint32_t serial)
{
zxdg_shell_v6_pong(xdg_shell, serial);
printf("ping pong!\n");
}
static const struct zxdg_shell_v6_listener xdg_shell_listener = {
.ping = xdg_shell_ping_handler,
};
static void xdg_toplevel_configure_handler(void *data,
struct zxdg_toplevel_v6 *xdg_toplevel, int32_t width, int32_t height,
struct wl_array *states)
{
printf("Configure: %dx%d\n", width, height);
}
static void xdg_toplevel_close_handler(void *data,
struct zxdg_toplevel_v6 *xdg_toplevel)
{
printf("Close\n");
}
static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
.configure = xdg_toplevel_configure_handler,
.close = xdg_toplevel_close_handler,
};
static void xdg_surface_configure_handler(void *data,
struct zxdg_surface_v6 *xdg_surface, uint32_t serial)
{
fprintf(stderr, "xdg_surface_configure_handler().\n");
zxdg_surface_v6_ack_configure(xdg_surface, serial);
}
static const struct zxdg_surface_v6_listener xdg_surface_listener = {
.configure = xdg_surface_configure_handler,
};
//=================
// File system
//=================
static int set_cloexec_or_close(int fd)
{
long flags;
if (fd == -1) {
return -1;
}
flags = fcntl(fd, F_GETFD);
if (flags == -1)
goto err;
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
goto err;
return fd;
err:
close(fd);
return -1;
}
static int create_tmpfile_cloexec(char *tmpname)
{
int fd;
#ifdef HAVE_MKOSTEMP
fd= mkostemp(tmpname, O_CLOEXEC);
if (fd >= 0) {
unlink(tmpname);
}
#else
fd = mkstemp(tmpname);
if (fd >= 0) {
fd = set_cloexec_or_close(fd);
unlink(tmpname);
}
#endif
return fd;
}
int os_create_anonymous_file(off_t size)
{
static const char template[] = "/blusher-shared-XXXXXX";
const char *path;
char *name;
int fd;
path = getenv("XDG_RUNTIME_DIR");
if (!path) {
errno = ENOENT;
return -1;
}
name = malloc(strlen(path) + sizeof(template));
if (!name) {
return -1;
}
strcpy(name, path);
strcat(name, template);
fd = create_tmpfile_cloexec(name);
free(name);
if (fd < 0) {
return -1;
}
if (ftruncate(fd, size) < 0) {
close(fd);
return -1;
}
return fd;
}
//==============
// Painting
//==============
static void paint_pixels()
{
uint32_t *pixel = shm_data;
fprintf(stderr, "Painting pixels.\n");
for (int n = 0; n < WIDTH * HEIGHT; ++n) {
if (n > 1100 && n < 1200) {
pixel[n] = 0xffff0000; // please ignore this
} else {
pixel[n] = 0x00ff0000;
}
}
}
static struct wl_buffer* create_buffer()
{
struct wl_shm_pool *pool;
int stride = WIDTH * 4; // 4 bytes per pixel
int size = stride * HEIGHT;
int fd;
struct wl_buffer *buff;
fd = os_create_anonymous_file(size);
if (fd < 0) {
fprintf(stderr, "Creating a buffer file for %d B filed: %m\n",
size);
exit(1);
}
shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm_data == MAP_FAILED) {
fprintf(stderr, "mmap filed: %m\n");
close(fd);
exit(1);
}
pool = wl_shm_create_pool(shm, fd, size);
buff = wl_shm_pool_create_buffer(
pool,
0,
WIDTH,
HEIGHT,
stride,
WL_SHM_FORMAT_ARGB8888
);
wl_shm_pool_destroy(pool);
return buff;
}
static void create_window()
{
buffer = create_buffer();
wl_surface_attach(surface, buffer, 0, 0);
// wl_surface_damage(surface, 0, 0, WIDTH, HEIGHT);
wl_surface_commit(surface);
}
static void shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
{
// struct display *d = data;
// d->formats |= (1 << format);
fprintf(stderr, "Format %d\n", format);
}
struct wl_shm_listener shm_listener = {
shm_format,
};
//==============
// Global
//==============
static void global_registry_handler(void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
{
if (strcmp(interface, "wl_compositor") == 0) {
fprintf(stderr, "Interface is <wl_compositor>.\n");
compositor = wl_registry_bind(
registry,
id,
&wl_compositor_interface,
version
);
} else if (strcmp(interface, "zxdg_shell_v6") == 0) {
fprintf(stderr, "Interface is <zxdg_shell_v6>.\n");
xdg_shell = wl_registry_bind(registry, id, &zxdg_shell_v6_interface, 1);
} else if (strcmp(interface, "wl_shm") == 0) {
fprintf(stderr, "Interface is <wl_shm>.\n");
shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(shm, &shm_listener, NULL);
} else {
// printf("(%d) Got a registry event for <%s> id <%d>\n",
// version, interface, id);
}
}
static void global_registry_remover(void *data, struct wl_registry *registry,
uint32_t id)
{
printf("Got a registry losing event for <%d>\n", id);
}
static const struct wl_registry_listener registry_listener = {
global_registry_handler,
global_registry_remover
};
//==============
// Main
//==============
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
display = wl_display_connect(NULL);
if (display == NULL) {
fprintf(stderr, "Can't connect to display.\n");
exit(1);
}
printf("Connected to display.\n");
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &registry_listener, NULL);
wl_display_dispatch(display);
// wl_display_roundtrip(display);
// Check compositor.
fprintf(stderr, " - Checking compositor...\n");
if (compositor == NULL) {
fprintf(stderr, "Can't find compositor.\n");
exit(1);
}
// Check surface.
fprintf(stderr, " - Checking surface...\n");
surface = wl_compositor_create_surface(compositor);
if (surface == NULL) {
fprintf(stderr, "Can't create surface.\n");
exit(1);
}
if (xdg_shell == NULL) {
fprintf(stderr, "Haven't got a Xdg shell.\n");
exit(1);
}
zxdg_shell_v6_add_listener(xdg_shell, &xdg_shell_listener, NULL);
// Check shell surface.
xdg_surface =
zxdg_shell_v6_get_xdg_surface(xdg_shell, surface);
zxdg_surface_v6_add_listener(xdg_surface, &xdg_surface_listener, NULL);
xdg_toplevel = zxdg_surface_v6_get_toplevel(xdg_surface);
zxdg_toplevel_v6_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL);
// Signal that the surface is ready to be configured.
wl_surface_commit(surface);
// Wait for the surface to be configured.
wl_display_roundtrip(display);
create_window();
paint_pixels();
// wl_surface_attach(surface, buffer, 0, 0);
// wl_surface_commit(surface);
while (wl_display_dispatch(display) != -1) {
;
}
wl_display_disconnect(display);
printf("Disconnected from display.\n");
return 0;
}
# Makefile
default:
wayland-scanner client-header /usr/share/wayland-protocols/unstable/xdg-shell/xdg-shell-unstable-v6.xml xdg-shell.h
wayland-scanner public-code /usr/share/wayland-protocols/unstable/xdg-shell/xdg-shell-unstable-v6.xml xdg-shell.c
gcc -lwayland-client -lwayland-egl -lEGL -lGLESv2 main.c xdg-shell.c
But when I set pixel to 0x00000000, then it is fully transparent.
And in some tests, subsurfaces are completely transparent even there are color bits set. I want to know what is prevent the transparent toplevel surface with color bits.
If your wayland compositor supports alpha-compositing-v1 protocol you can use it do what you want.
In short; get a reference to zwp_alpha_compositing_v1 struct in you registry handler then after creating your surface you set it like this:
struct zwp_blending_v1* blending = zwp_alpha_compositing_v1_get_blending(<YOUR_ZWP_ALPHA_COMPOSITING>, <YOUR_WL_SURFACE>);
zwp_blending_v1_set_blending(blending, ZWP_BLENDING_V1_BLENDING_EQUATION_STRAIGHT);
This is an equivalent to (src_alpha, one_minus_src_alpha) blending.

ioctl in kernel module: why some commands are not executed?

I attach here my kernel module I developed and the test I am using at application level
memalloc.c
/*
* DMA memory allocation
* This kernel module allocates coherent, non-cached memory
* and returns the physical and virtual address of the allocated buffer
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include "memalloc.h"
#define DEVICE_NAME "memalloc"
// Max number of buffers
#define BUFFER_MAX_NUMBER 16
// Structure for buffer information
struct bufferInfo {
int active;
int size;
dma_addr_t handle;
int virtualAddress;
int *kernelAddress;
};
static struct bufferInfo bufferInfoTable[BUFFER_MAX_NUMBER];
// Defines which buffer is currently active - for mmap
static int activeBufferID;
struct memAllocIF {
struct device *device_p;
dev_t dev_node;
struct cdev cdev;
struct class *class_p;
};
static struct memAllocIF interface;
// Methods
static int releaseBuffer(int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
printk("Releasing buffer %d\n", i);
bufferInfoTable[i].active = 0;
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
return 0;
}
static int reserveBuffer(size_t size)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active == 0)
{
printk("Reserving buffer %d\n", i);
bufferInfoTable[i].active = 1;
break;
}
}
if (i < BUFFER_MAX_NUMBER)
{
bufferInfoTable[i].kernelAddress = dma_alloc_coherent(NULL, size, &bufferInfoTable[i].handle, GFP_KERNEL);
if (bufferInfoTable[i].kernelAddress == NULL)
{
printk("Allocation failure\n");
return -1;
}
bufferInfoTable[i].size = (int)size;
return i;
}
else
{
printk("No buffer available\n");
return -1;
}
}
static void cleanup(void)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active != 0)
{
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
bufferInfoTable[i].active = 0;
}
}
}
static unsigned int memAllocGetVirtual (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
if (bufferInfoTable[i].active == 0)
{
printk("Inactive buffer - ID %d\n", i);
return -1;
}
printk("request for buffer %d: vaddr = %X\n", i, (unsigned int)bufferInfoTable[i].virtualAddress);
return bufferInfoTable[i].virtualAddress;
}
static unsigned int memAllocGetPhysical (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
return (unsigned int)bufferInfoTable[i].handle;
}
static long memAllocIoctl (struct file *fd, unsigned int cmd, unsigned long arg)
{
printk("received command %u arg %lu\n", cmd, arg);
switch(cmd)
{
case MEMALLOC_RESERVE:
return reserveBuffer(arg);
break;
case MEMALLOC_RELEASE:
return releaseBuffer(arg);
break;
case MEMALLOC_GET_VIRTUAL:
return memAllocGetVirtual(arg);
break;
case MEMALLOC_GET_PHYSICAL:
return memAllocGetPhysical(arg);
break;
case MEMALLOC_ACTIVATE_BUFFER:
if (arg > BUFFER_MAX_NUMBER || bufferInfoTable[arg].active == 0)
{
printk("Wrong bufferID %lu\n", arg);
return -1;
}
activeBufferID = arg;
return arg;
break;
default:
printk("Wrong command: %d\n", cmd);
return -1;
break;
}
}
static int memAllocMmap (struct file *fd, struct vm_area_struct *vma)
{
bufferInfoTable[activeBufferID].virtualAddress = dma_common_mmap(interface.device_p, vma, bufferInfoTable[activeBufferID].kernelAddress, bufferInfoTable[activeBufferID].handle, vma->vm_end-vma->vm_start);
printk("mmap for idx %d: vaddr = %X\n", activeBufferID, (int)bufferInfoTable[activeBufferID].virtualAddress);
return bufferInfoTable[activeBufferID].virtualAddress;
}
static int memAllocRelease(struct inode *in, struct file *fd)
{
cleanup();
return 0;
}
static int memAllocOpen(struct inode *ino, struct file *file)
{
file->private_data = container_of(ino->i_cdev, struct memAllocIF, cdev);
return 0;
}
static struct file_operations fops = {
.unlocked_ioctl = memAllocIoctl,
.mmap = memAllocMmap,
.release = memAllocRelease,
.open = memAllocOpen
};
static int __init memAllocInit(void)
{
int rc;
int i;
static struct class *local_class_p = NULL;
printk("Loading DMA allocation module\n");
// Allocate a character device from the kernel for this driver
rc = alloc_chrdev_region(&interface.dev_node, 0, 1, DEVICE_NAME);
if (rc)
{
printk("Unable to get a char device number\n");
return rc;
}
// Initialize the ter device data structure before registering the character device with the kernel
cdev_init(&interface.cdev, &fops);
rc = cdev_add(&interface.cdev, interface.dev_node, 1);
if (rc)
{
printk("Unable to add char device\n");
cdev_del(&interface.cdev);
return rc;
}
// Create the device in sysfs which will allow the device node in /dev to be created
local_class_p = class_create(THIS_MODULE, DEVICE_NAME);
interface.class_p = local_class_p;
// Create the device node in /dev so the device is accessible as a character device
interface.device_p = device_create(interface.class_p, NULL, interface.dev_node, NULL, DEVICE_NAME);
if (IS_ERR(interface.device_p))
{
printk("Unable to create the device\n");
class_destroy(interface.class_p);
cdev_del(&interface.cdev);
return rc;
}
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
bufferInfoTable[activeBufferID].active = 0;
}
return 0;
}
static void __exit my_memAllocExit(void)
{
printk("Module unloading\n");
cleanup();
cdev_del(&interface.cdev);
device_destroy(interface.class_p, interface.dev_node);
class_destroy(interface.class_p);
unregister_chrdev_region(interface.dev_node, 1);
}
module_init(memAllocInit);
module_exit(my_memAllocExit);
MODULE_AUTHOR("me");
MODULE_DESCRIPTION("Create a buffer and return physical and virtual address, for DMA userspace driver");
MODULE_LICENSE("GPL");
memalloc.h
#ifndef MEMALLOC_H
#define MEMALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <linux/types.h>
#include <asm/ioctl.h>
static long memAllocIoctl (struct file *, unsigned int, unsigned long);
static int memAllocMmap (struct file *, struct vm_area_struct *);
static int memAllocRelease (struct inode *, struct file *);
static int memAllocOpen(struct inode *, struct file *);
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
#ifdef __cplusplus
}
#endif
#endif /* MEMALLOC_H */
test.c
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
// derive this from memalloc.h
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
int main ()
{
int memAllocFd;
volatile int iVaddr;
volatile int oVaddr;
volatile int iVaddr_2;
volatile int oVaddr_2;
volatile void * iPaddr;
volatile void * oPaddr;
int iBufID;
int oBufID;
int size = 2048;
memAllocFd = open("/dev/memalloc", O_RDWR);
// create iBuffer
iBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
iPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, iBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, iBufID);
iVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, iBufID);
/*
if (iVaddr != iVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", iBufID, iVaddr, iVaddr_2);
}
*/
// create oBuffer
oBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
oPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, oBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, oBufID);
oVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, oBufID);
/*
if (oVaddr != oVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", oBufID, oVaddr, oVaddr_2);
}
*/
ioctl(memAllocFd, MEMALLOC_RELEASE, iBufID);
ioctl(memAllocFd, MEMALLOC_RELEASE, oBufID);
return 0;
}
Result of the test is
received command 0 arg 2048
Reserving buffer 0
received command 3 arg 0
received command 4 arg 0
mmap for idx 0: vaddr = 0
received command 0 arg 2048
Reserving buffer 1
received command 3 arg 1
received command 4 arg 1
mmap for idx 1: vaddr = 0
received command 1 arg 0
Releasing buffer 0
received command 1 arg 1
Releasing buffer 1
Which means that all ioctl calls with arg=MEMALLOC_GET_VIRTUAL are not executed, while all the others are.
What can be the reason for that?
Thanks,
Max

How to return to menu in Socket Client-Server

I've writen this code but it doesn't work correctly.
This is menu interface:
*************ENCODE_DECODE_BASE64**************
******* 1. Encode ********
******* 2. Decode ********
******* 3. Exit ********
***********************************************
When i choose 1, "Encode". The function runs but the process exits.
I want when I choose 1, the function to run and then after that, the menu to display again.
Can you help me?
Here is Clientcode:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024
// read filename
char *inputString(int size){
int test=0;
char *s=(char*)malloc(size);
do{
if(test!=0){
printf("File not found !!!!!!");
}
fgets(s,size,stdin);
test++;
}while(strlen(s)<=1);
return strtok(s,"\n");
}
int main(int argc, char *argv[]){
int sockfd;
struct sockaddr serverAddr; //server address
char buff[1024];
struct sockaddr_in inAddr;
long int sentBytes,revedBytes;
sockfd=socket(AF_INET,SOCK_STREAM,0); // create socket
if (sockfd == -1)
{
printf("ERROR opening socket\n");
return 1;
}
printf("Socket done\n");
inAddr.sin_family=AF_INET; //default
inAddr.sin_port=htons(5500); // service port
inet_aton("127.0.0.1",&inAddr.sin_addr);
//connectting
if(connect(sockfd,(struct sockaddr *)&inAddr,sizeof(struct sockaddr))<0){
printf("Connect failed.\n");
return 1;
}
printf("Connection accepted\n");
char *FileName; // file input
char *Result; // file return
int choice;
do{
printf("\n*************ENCODE_DECODE_BASE64**************");
printf("\n******* 1. Encode ********");
printf("\n******* 2. Decode ********");
printf("\n******* 3. Exit ********");
printf("\n***********************************************\n");
printf("Choice: ");
choice = getchar();
while(getchar() !='\n');
switch(choice)
{
case '1':
//demo encode////////////////////////////////////////
send(sockfd,"encode",5,0); // send to server when choose 1
printf("File Encode : ");
FileName = inputString(20);
FILE *fpt = fopen(FileName,"r");
if(fpt==NULL){
printf("File not found");
return -1;
}
printf("File Result: ");
Result = inputString(20);
FILE *ft = fopen(Result,"w");
while(!feof(fpt)){
if (fgets(buff,MAX,fpt) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft,"%s\n",buff);
}
}
printf("Encode done!thanks you !\n");
//close(sockfd);
fclose(fpt);fclose(ft);
return 0;
break;
//decode ///////////////////////////////////////////////
case '2':
send(sockfd,"decode",6,0);
printf("File Decode : ");
FileName = inputString(20);
FILE *fpt1 = fopen(FileName,"r");
if(fpt1==NULL){
printf("File not found");
return -1;
}
printf("File Result : ");
Result = inputString(20);
FILE *ft1 = fopen(Result,"w");
while(!feof(fpt1)){
if (fgets(buff,MAX,fpt1) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft1,"%s",buff);
}
}
printf("Decode done ! thanks you !\n");
//close(sockfd);
fclose(fpt1);fclose(ft1);
return 0;
break;
///////////////////////////////////////////////////////
case '3':
printf("Thanks!\n");
break;
default: printf("wrong number, please try again!\n"); break;
//end choice///////////////////////////////////////
}
}while(choice!='3');
//end menu
//close(sockfd);
//return 0;
}
and here is ServerCode:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
void sig_chld(int signo) //child
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG))>0)
printf("child %d terminated\n", pid);
return;
}
int main()
{
int listen_sock, conn_sock;
int server_len, client_len,choice;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
char myb64[1024] = ""; //encode
char mydst[1024] = ""; //decode
int sentBytes,revedBytes,bytes_readi;
char buff[1024]; //buffer to send data
listen_sock = socket(AF_INET, SOCK_STREAM, 0); //create socket
if (listen_sock == -1)
{
printf("ERROR opening socket\n");
return 0;
}
printf("Socket done\n");
//Thiet lap dia chi server
server_address.sin_family = AF_INET; //default
inet_aton("127.0.0.1",&server_address.sin_addr); //ip server
server_address.sin_port = htons(5500); // port server
server_len = sizeof(server_address);
if(bind(listen_sock, (struct sockaddr *)&server_address,server_len)<0)
{
printf("ERROR on binding\n");
return 0;
}
printf("Bind done\n");
int check = listen(listen_sock,10);
if (check == -1)
{
printf("Error connect");
return 0;
}
printf("Waiting connect..\n");
while(1) {
client_len = sizeof(client_address);
conn_sock = accept(listen_sock,(struct sockaddr *)&client_address, &client_len);
if(conn_sock==-1){
printf("Error connect\n");
return 1;
}else{
printf("Accept new connection\n");
}
if(fork() == 0){
close(listen_sock);
do{
revedBytes = recv(conn_sock,buff,1024,0);
buff[revedBytes]='\0';
if(strcmp(buff,"mahoa")==0) choice=1;
else if(strcmp(buff,"giaima")==0) choice=2; else choice = 3;
switch(choice)
{
case 1:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client encode : %s\n",buff);
b64_encode(buff, myb64); //ma hoa
sentBytes=send(conn_sock,myb64,1024,0); //gui lai string da ma hoa cho client
}
close(conn_sock);//Dong ket noi cua client
exit(0);
break;
case 2:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client decode: %s\n",buff);
b64_decode(buff,mydst); // giaima
sentBytes=send(conn_sock,mydst,1024,0);
}
close(conn_sock);
exit(0);
break;
case 3:break;
}
}while(choice!=3);
break;
}
signal(SIGCHLD,sig_chld);
close(conn_sock);
}
return 1;
}

JPEG streaming with live555

I want to stream JPEG images or motion-JPEG file through live 555. But the problem is that in live 555 implementation for Jpegs is not available. Anyone can help ??
You can find a implementation that was posted to the devel mailing list http://lists.live555.com/pipermail/live-devel/2012-February/014672.html.
The code and a sample is available but this modification was rejected by live555 maintainer.
First we need to implement an MJPEGVideoSource than can feed a JPEGVideoRTPSink.
#include "JPEGVideoSource.hh"
class MJPEGVideoSource : public JPEGVideoSource
{
public:
static MJPEGVideoSource* createNew (UsageEnvironment& env, FramedSource* source)
{
return new MJPEGVideoSource(env,source);
}
virtual void doGetNextFrame()
{
if (m_inputSource)
m_inputSource->getNextFrame(fTo, fMaxSize, afterGettingFrameSub, this, FramedSource::handleClosure, this);
}
virtual void doStopGettingFrames()
{
FramedSource::doStopGettingFrames();
if (m_inputSource)
m_inputSource->stopGettingFrames();
}
static void afterGettingFrameSub(void* clientData, unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
MJPEGVideoSource* source = (MJPEGVideoSource*)clientData;
source->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
}
void afterGettingFrame(unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
int headerSize = 0;
bool headerOk = false;
fFrameSize = 0;
for (unsigned int i = 0; i < frameSize ; ++i)
{
// SOF
if ( (i+8) < frameSize && fTo[i] == 0xFF && fTo[i+1] == 0xC0 )
{
m_height = (fTo[i+5]<<5)|(fTo[i+6]>>3);
m_width = (fTo[i+7]<<5)|(fTo[i+8]>>3);
}
// DQT
if ( (i+5+64) < frameSize && fTo[i] == 0xFF && fTo[i+1] == 0xDB)
{
if (fTo[i+4] ==0)
{
memcpy(m_qTable, fTo + i + 5, 64);
m_qTable0Init = true;
}
else if (fTo[i+4] ==1)
{
memcpy(m_qTable + 64, fTo + i + 5, 64);
m_qTable1Init = true;
}
}
// End of header
if ( (i+1) < frameSize && fTo[i] == 0x3F && fTo[i+1] == 0x00 )
{
headerOk = true;
headerSize = i+2;
break;
}
}
if (headerOk)
{
fFrameSize = frameSize - headerSize;
memmove( fTo, fTo + headerSize, fFrameSize );
}
fNumTruncatedBytes = numTruncatedBytes;
fPresentationTime = presentationTime;
fDurationInMicroseconds = durationInMicroseconds;
afterGetting(this);
}
virtual u_int8_t type() { return 1; };
virtual u_int8_t qFactor() { return 128; };
virtual u_int8_t width() { return m_width; };
virtual u_int8_t height() { return m_height; };
u_int8_t const* quantizationTables( u_int8_t& precision, u_int16_t& length )
{
length = 0;
precision = 0;
if ( m_qTable0Init && m_qTable1Init )
{
precision = 8;
length = sizeof(m_qTable);
}
return m_qTable;
}
protected:
MJPEGVideoSource(UsageEnvironment& env, FramedSource* source) : JPEGVideoSource(env),
m_inputSource(source),
m_width(0),
m_height(0),
m_qTable0Init(false),
m_qTable1Init(false)
{
memset(&m_qTable,0,sizeof(m_qTable));
}
virtual ~MJPEGVideoSource()
{
Medium::close(m_inputSource);
}
protected:
FramedSource* m_inputSource;
u_int8_t m_width;
u_int8_t m_height;
u_int8_t m_qTable[128];
bool m_qTable0Init;
bool m_qTable1Init;
};
Next we can use it as a video source in order to build a simple RTSP server:
#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"
#include "GroupsockHelper.hh"
#include "MJPEGVideoSource.hh"
char const* inputFileName = "test.mjpeg";
int main(int argc, char** argv) {
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
// Create 'groupsocks' for RTP and RTCP:
struct in_addr destinationAddress;
destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);
const unsigned short rtpPortNum = 18888;
const unsigned short rtcpPortNum = rtpPortNum+1;
const unsigned char ttl = 255;
const Port rtpPort(rtpPortNum);
const Port rtcpPort(rtcpPortNum);
Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
rtpGroupsock.multicastSendOnly(); // we're a SSM source
Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
rtcpGroupsock.multicastSendOnly(); // we're a SSM source
// Create a 'JPEG Video RTP' sink from the RTP 'groupsock':
RTPSink* videoSink = JPEGVideoRTPSink::createNew(*env, &rtpGroupsock);
// Create (and start) a 'RTCP instance' for this RTP sink:
const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char*)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = '\0'; // just in case
RTCPInstance* rtcp = RTCPInstance::createNew(*env, &rtcpGroupsock,
estimatedSessionBandwidth, CNAME,
videoSink, NULL /* we're a server */,
True /* we're a SSM source */);
// Note: This starts RTCP running automatically
RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
ServerMediaSession* sms = ServerMediaSession::createNew(*env, "testStream", inputFileName,"Session streamed by \"testMJPEGVideoStreamer\"",
True /*SSM*/);
sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));
rtspServer->addServerMediaSession(sms);
char* url = rtspServer->rtspURL(sms);
*env << "Play this stream using the URL \"" << url << "\"\n";
delete[] url;
// Start the streaming:
*env << "Beginning streaming...\n";
// Open the input file as a 'byte-stream file source':
ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(*env, inputFileName);
if (fileSource == NULL) {
*env << "Unable to open file \"" << inputFileName
<< "\" as a byte-stream file source\n";
exit(1);
}
// Create the MJPEG video source:
MJPEGVideoSource* videoSource = MJPEGVideoSource::createNew(*env, fileSource);
// Finally, start playing:
*env << "Beginning to read from file...\n";
videoSink->startPlaying(*videoSource, NULL, NULL);
env->taskScheduler().doEventLoop();
return 0;
}
Hope you have done it but if not-
see this Jpeg Streaming using live555
This is doing the same thing as you have asked to stream the images/Jpegs.
For MJpegs you'll have to do the same process.

How to access (copy/modify) particular appfiledirectory from the name of its background process in iPhone?

I have list of background processes and their pid running in background in iphone got from following code. My projects requirement is-
(its like an antivirus)
Get information on each process
a. Name
b. Size
c. Last Modified Date/Time
d. Associated Files
e. What the process is accessing from all interfaces (storage, USB, Bluetooth, Wi-Fi etc)
f. Any other information available
Thanks in advance.
#import <mach/mach_host.h>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/sysctl.h"
#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
- (void)viewDidLoad
{
[super viewDidLoad];
[self printProcessInfo];
}
-(int) printProcessInfo
{
int mib[5];
struct kinfo_proc *procs = NULL, *newprocs;
int i, st, nprocs;
size_t miblen, size;
/* Set up sysctl MIB */
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
mib[3] = 0;
miblen = 4;
/* Get initial sizing */
st = sysctl(mib, miblen, NULL, &size, NULL, 0);
/* Repeat until we get them all ... */
do {
/* Room to grow */
size += size / 10;
newprocs = realloc(procs, size);
if (!newprocs) {
if (procs) {
free(procs);
}
perror("Error: realloc failed.");
return (0);
}
procs = newprocs;
st = sysctl(mib, miblen, procs, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st != 0) {
perror("Error: sysctl(KERN_PROC) failed.");
return (0);
}
/* Do we match the kernel? */
assert(size % sizeof(struct kinfo_proc) == 0);
nprocs = size / sizeof(struct kinfo_proc);
if (!nprocs) {
perror("Error: printProcessInfo.");
return(0);
}
printf(" PID\tName\n");
printf("-----\t--------------\n");
self.lists = [[NSMutableString alloc] init];
for (i = nprocs-1; i >=0; i--) {
printf("%5d\t%s\n",(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm);
}
NSLog(#"%#",lists);
listsText.text = lists;
free(procs);
return (0);
}
answer a)name of process you are getting in above code.
answer d)to get associated files,pass pid of process to this function (we have got pid in questions code)-
void print_argv_of_pid(int pid) {
printf("%d\n", pid);
int mib[3], argmax, nargs, c = 0;
size_t size;
char *procargs, *sp, *np, *cp;
extern int eflg;
int show_args = 1;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) {
goto ERROR_A;
}
/* Allocate space for the arguments. */
procargs = (char *)malloc(argmax);
if (procargs == NULL) {
goto ERROR_A;
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pid;
size = (size_t)argmax;
if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) {
goto ERROR_B;
}
memcpy(&nargs, procargs, sizeof(nargs));
cp = procargs + sizeof(nargs);
/* Skip the saved exec_path. */
for (; cp < &procargs[size]; cp++) {
if (*cp == '\0') {
/* End of exec_path reached. */
break;
}
}
if (cp == &procargs[size]) {
goto ERROR_B;
}
/* Skip trailing '\0' characters. */
for (; cp < &procargs[size]; cp++) {
if (*cp != '\0') {
/* Beginning of first argument reached. */
break;
}
}
if (cp == &procargs[size]) {
goto ERROR_B;
}
/* Save where the argv[0] string starts. */
sp = cp;
for (np = NULL; c < nargs && cp < &procargs[size]; cp++) {
if (*cp == '\0') {
c++;
if (np != NULL) {
/* Convert previous '\0'. */
*np = ' ';
} else {
/* *argv0len = cp - sp; */
}
/* Note location of current '\0'. */
np = cp;
if (!show_args) {
/*
* Don't convert '\0' characters to ' '.
* However, we needed to know that the
* command name was terminated, which we
* now know.
*/
break;
}
}
}
if (np == NULL || np == sp) {
/* Empty or unterminated string. */
goto ERROR_B;
}
/* Make a copy of the string. */
printf("%s\n", sp);
/* Clean up. */
free(procargs);
return;
ERROR_B:
free(procargs);
ERROR_A:
printf("error");
}
answer b),c)-size and access times-
struct stat st;
//pass filepath upto /.app/ to stat function (use 'componentsseparatedby' of nsstring apply on full path which we got in answer d's code above)
if (stat(filename, &st)) {
perror(filename);
} else {
printf("%s: mtime = %lld.%.9ld\n", filename, (long long)st.st_mtimespec.tv_sec, st.st_mtimespec.tv_nsec);
printf("File size: %lld bytes\n",
(long long) st.st_size);
printf("Last status change: %s", ctime(&st.st_ctime));
printf("Last file access: %s", ctime(&st.st_atime));
printf("Last file modification: %s", ctime(&st.st_mtime));
}
other information-
TO KILL THE PROCESS-
just pass pid of process to be killed-
int pid_exists(long pid)
{
int kill_ret;
// save some time if it's an invalid PID
if (pid < 0) {
return 0;
}
// if kill returns success of permission denied we know it's a valid PID
kill_ret = kill(pid , 0);
if ( (0 == kill_ret) || (EPERM == errno) ) {
return 1;
}
// otherwise return 0 for PID not found
return 0;
}