R magic number from the R source

Implements the writing/reading of the version and format of an RData file or blob.
This commit is contained in:
2020-09-03 14:13:56 +01:00
parent 83876e723e
commit 1db6470790
2 changed files with 138 additions and 0 deletions

106
src/Rmagic.c Normal file
View File

@@ -0,0 +1,106 @@
#include "Rmagic.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int R_WriteMagic(FILE *fp, int number)
{
unsigned char buf[5];
size_t res;
number = abs(number);
switch (number) {
case R_MAGIC_ASCII_V1: /* Version 1 - R Data, ASCII Format */
strcpy((char*)buf, "RDA1");
break;
case R_MAGIC_BINARY_V1: /* Version 1 - R Data, Binary Format */
strcpy((char*)buf, "RDB1");
break;
case R_MAGIC_XDR_V1: /* Version 1 - R Data, XDR Binary Format */
strcpy((char*)buf, "RDX1");
break;
case R_MAGIC_ASCII_V2: /* Version 2 - R Data, ASCII Format */
strcpy((char*)buf, "RDA2");
break;
case R_MAGIC_BINARY_V2: /* Version 2 - R Data, Binary Format */
strcpy((char*)buf, "RDB2");
break;
case R_MAGIC_XDR_V2: /* Version 2 - R Data, XDR Binary Format */
strcpy((char*)buf, "RDX2");
break;
case R_MAGIC_ASCII_V3: /* Version >=3 - R Data, ASCII Format */
strcpy((char*)buf, "RDA3");
break;
case R_MAGIC_BINARY_V3: /* Version >=3 - R Data, Binary Format */
strcpy((char*)buf, "RDB3");
break;
case R_MAGIC_XDR_V3: /* Version >=3 - R Data, XDR Binary Format */
strcpy((char*)buf, "RDX3");
break;
default:
buf[0] = (unsigned char)((number / 1000) % 10 + '0');
buf[1] = (unsigned char)((number / 100) % 10 + '0');
buf[2] = (unsigned char)((number / 10) % 10 + '0');
buf[3] = (unsigned char)(number % 10 + '0');
}
buf[4] = '\n';
res = fwrite((char*)buf, sizeof(char), 5, fp);
if(res != 5) {
return -1;
}
return 0;
}
int R_ReadMagic(FILE *fp)
{
unsigned char buf[6];
int d1, d2, d3, d4;
size_t count;
count = fread((char*)buf, sizeof(char), 5, fp);
if (count != 5) {
if (count == 0) {
return R_MAGIC_EMPTY;
} else {
return R_MAGIC_CORRUPT;
}
}
/* Version 1 */
if (strncmp((char*)buf, "RDA1\n", 5) == 0) {
return R_MAGIC_ASCII_V1;
} else if (strncmp((char*)buf, "RDB1\n", 5) == 0) {
return R_MAGIC_BINARY_V1;
} else if (strncmp((char*)buf, "RDX1\n", 5) == 0) {
return R_MAGIC_XDR_V1;
}
/* Version 2 */
if (strncmp((char*)buf, "RDA2\n", 5) == 0) {
return R_MAGIC_ASCII_V2;
} else if (strncmp((char*)buf, "RDB2\n", 5) == 0) {
return R_MAGIC_BINARY_V2;
} else if (strncmp((char*)buf, "RDX2\n", 5) == 0) {
return R_MAGIC_XDR_V2;
}
/* Version 3 */
if (strncmp((char*)buf, "RDA3\n", 5) == 0) {
return R_MAGIC_ASCII_V3;
} else if (strncmp((char*)buf, "RDB3\n", 5) == 0) {
return R_MAGIC_BINARY_V3;
} else if (strncmp((char*)buf, "RDX3\n", 5) == 0) {
return R_MAGIC_XDR_V3;
} else if (strncmp((char *)buf, "RD", 2) == 0) {
return R_MAGIC_MAYBE_TOONEW;
}
/* Intel gcc seems to screw up a single expression here */
d1 = (buf[3] - '0') % 10;
d2 = (buf[2] - '0') % 10;
d3 = (buf[1] - '0') % 10;
d4 = (buf[0] - '0') % 10;
return d1 + 10 * d2 + 100 * d3 + 1000 * d4;
}

32
src/Rmagic.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef __R_MAGIC_H__
#define __R_MAGIC_H__
#include <stdio.h>
#define R_STREAM_VERSION 3
#define R_MAGIC_ASCII_V3 3001
#define R_MAGIC_BINARY_V3 3002
#define R_MAGIC_XDR_V3 3003
#define R_MAGIC_ASCII_V2 2001
#define R_MAGIC_BINARY_V2 2002
#define R_MAGIC_XDR_V2 2003
#define R_MAGIC_ASCII_V1 1001
#define R_MAGIC_BINARY_V1 1002
#define R_MAGIC_XDR_V1 1003
#define R_MAGIC_EMPTY 999
#define R_MAGIC_CORRUPT 998
#define R_MAGIC_MAYBE_TOONEW 997
/* pre-1 formats (R < 0.99.0) */
#define R_MAGIC_BINARY 1975
#define R_MAGIC_ASCII 1976
#define R_MAGIC_XDR 1977
#define R_MAGIC_BINARY_VERSION16 1971
#define R_MAGIC_ASCII_VERSION16 1972
int R_WriteMagic(FILE *fp, int number);
int R_ReadMagic(FILE *fp);
#endif // __R_MAGIC_H__