shithub: rtmp

ref: 0ec0e4fde657c442431548180c91018078c2bf3c
dir: /amf.c/

View raw version
#include <u.h>
#include <libc.h>
#include "amf.h"

enum {
	Anum,
	Aarr = 8,
	Aend,
	Alstr = 12,
};

u8int *
amfi16(u8int *p, u8int *e, s16int i)
{
	if(p == nil)
		return nil;
	if(e-p < 2){
		werrstr("buffer short");
		return nil;
	}
	*p++ = i >> 8;
	*p++ = i;

	return p;
}

u8int *
amfi24(u8int *p, u8int *e, s32int i)
{
	if(p == nil)
		return nil;
	if(e-p < 3){
		werrstr("buffer short");
		return nil;
	}
	*p++ = i >> 16;
	*p++ = i >> 8;
	*p++ = i;

	return p;
}

u8int *
amfi32(u8int *p, u8int *e, s32int i)
{
	if(p == nil)
		return nil;
	if(e-p < 4){
		werrstr("buffer short");
		return nil;
	}
	*p++ = i >> 24;
	*p++ = i >> 16;
	*p++ = i >> 8;
	*p++ = i;

	return p;
}

u8int *
amfnum(u8int *p, u8int *e, double v)
{
	union {
		double v;
		u64int u;
	}x;

	if(p == nil)
		return nil;
	if(p+8 > e){
		werrstr("buffer short");
		return nil;
	}
	x.v = v;
	*p++ = x.u >> 56;
	*p++ = x.u >> 48;
	*p++ = x.u >> 40;
	*p++ = x.u >> 32;
	*p++ = x.u >> 24;
	*p++ = x.u >> 16;
	*p++ = x.u >> 8;
	*p++ = x.u;

	return p;
}

u8int *
amfkvnum(u8int *p, u8int *e, char *name, double v)
{
	int n;

	if(p == nil)
		return nil;
	if((n = strlen(name)) > 0xffff){
		werrstr("string too long");
		return nil;
	}
	if(p+2+n+8 > e){
		werrstr("buffer short");
		return nil;
	}
	p = amfi16(p, e, n);
	p = (u8int*)memmove(p, name, n) + n;

	return amfnum(p, e, v);
}

u8int *
amfstr(u8int *p, u8int *e, char *s)
{
	int n;

	if(p == nil)
		return nil;
	n = strlen(s);
	if(p+1+4+n > e){
		werrstr("string too long");
		return nil;
	}
	*p++ = Alstr;

	return (u8int*)memmove(amfi32(p, e, n), s, n) + n;
}

u8int *
amfarr(u8int *p, u8int *e)
{
	if(p == nil)
		return nil;
	if(p == e){
		werrstr("buffer short");
		return nil;
	}
	*p++ = Aarr;

	return p;
}

u8int *
amfend(u8int *p, u8int *e)
{
	return amfi24(p, e, Aend);
}