Skip to content

Commit

Permalink
Refactor into a separate header file
Browse files Browse the repository at this point in the history
  • Loading branch information
certik committed Jun 18, 2021
1 parent e477caf commit e5217e8
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 237 deletions.
168 changes: 168 additions & 0 deletions src/lfortran/bwriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#ifndef LFORTRAN_BWRITER_H
#define LFORTRAN_BWRITER_H

#include <lfortran/exception.h>

namespace LFortran {

std::string static inline uint64_to_string(uint64_t i) {
char bytes[4];
bytes[0] = (i >> 24) & 0xFF;
bytes[1] = (i >> 16) & 0xFF;
bytes[2] = (i >> 8) & 0xFF;
bytes[3] = i & 0xFF;
return std::string(bytes, 4);
}

uint64_t static inline string_to_uint64(const char *s) {
// The cast from signed char to unsigned char is important,
// otherwise the signed char shifts return wrong value for negative numbers
const uint8_t *p = (const unsigned char*)s;
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}

uint64_t static inline string_to_uint64(const std::string &s) {
return string_to_uint64(&s[0]);
}

// BinaryReader / BinaryWriter encapsulate access to the file by providing
// primitives that other classes just use.
class BinaryWriter
{
private:
std::string s;
public:
std::string get_str() {
return s;
}

void write_int8(uint8_t i) {
char c=i;
s.append(std::string(&c, 1));
}

void write_int64(uint64_t i) {
s.append(uint64_to_string(i));
}

void write_string(const std::string &t) {
write_int64(t.size());
s.append(t);
}
};

class BinaryReader
{
private:
std::string s;
size_t pos;
public:
BinaryReader(const std::string &s) : s{s}, pos{0} {}

uint8_t read_int8() {
if (pos+1 > s.size()) {
throw LFortranException("read_int8: String is too short for deserialization.");
}
uint8_t n = s[pos];
pos += 1;
return n;
}

uint64_t read_int64() {
if (pos+4 > s.size()) {
throw LFortranException("read_int64: String is too short for deserialization.");
}
uint64_t n = string_to_uint64(&s[pos]);
pos += 4;
return n;
}

std::string read_string() {
size_t n = read_int64();
if (pos+n > s.size()) {
throw LFortranException("read_string: String is too short for deserialization.");
}
std::string r = std::string(&s[pos], n);
pos += n;
return r;
}
};

// TextReader / TextWriter encapsulate access to the file by providing
// primitives that other classes just use. The file is a human readable
// text file. These classes are useful for debugging.
class TextWriter
{
private:
std::string s;
public:
std::string get_str() {
return s;
}

void write_int8(uint8_t i) {
s.append(std::to_string(i));
s += " ";
}

void write_int64(uint64_t i) {
s.append(std::to_string(i));
s += " ";
}

void write_string(const std::string &t) {
write_int64(t.size());
s.append(t);
s += " ";
}
};

class TextReader
{
private:
std::string s;
size_t pos;
public:
TextReader(const std::string &s) : s{s}, pos{0} {}

uint8_t read_int8() {
uint64_t n = read_int64();
if (n < 255) {
return n;
} else {
throw LFortranException("read_int8: Integer too large to fit 8 bits.");
}
}

uint64_t read_int64() {
std::string tmp;
while (s[pos] != ' ') {
tmp += s[pos];
pos++;
if (pos >= s.size()) {
throw LFortranException("read_int64: String is too short for deserialization.");
}
}
pos++;
uint64_t n = std::stoi(tmp);
return n;
}

std::string read_string() {
size_t n = read_int64();
if (pos+n > s.size()) {
throw LFortranException("read_string: String is too short for deserialization.");
}
std::string r = std::string(&s[pos], n);
pos += n;
if (s[pos] != ' ') {
throw LFortranException("read_string: Space expected.");
}
pos ++;
return r;
}
};

} // namespace LFortran

#endif // LFORTRAN_BWRITER_H
76 changes: 1 addition & 75 deletions src/lfortran/modfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,11 @@
#include <lfortran/asr_verify.h>
#include <lfortran/modfile.h>
#include <lfortran/serialization.h>
#include <lfortran/bwriter.h>


namespace LFortran {


class BinaryWriter
{
private:
std::string s;
public:
std::string get_str() {
return s;
}

void write_int8(uint8_t i) {
char c=i;
s.append(std::string(&c, 1));
}

void write_int64(uint64_t i) {
s.append(uint64_to_string(i));
}

void write_bool(bool b) {
if (b) {
write_int8(1);
} else {
write_int8(0);
}
}

void write_string(const std::string &t) {
write_int64(t.size());
s.append(t);
}
};

class BinaryReader
{
private:
std::string s;
size_t pos;
public:
BinaryReader(const std::string &s) : s{s}, pos{0} {}

uint8_t read_int8() {
if (pos+1 > s.size()) {
throw LFortranException("String is too short for deserialization.");
}
uint8_t n = s[pos];
pos += 1;
return n;
}

uint64_t read_int64() {
if (pos+4 > s.size()) {
throw LFortranException("String is too short for deserialization.");
}
uint64_t n = string_to_uint64(&s[pos]);
pos += 4;
return n;
}

bool read_bool() {
uint8_t b = read_int8();
return (b == 1);
}

std::string read_string() {
size_t n = read_int64();
if (pos+n > s.size()) {
throw LFortranException("String is too short for deserialization.");
}
std::string r = std::string(&s[pos], n);
pos += n;
return r;
}
};

const std::string lfortran_modfile_type_string = "LFortran Modfile";

// The save_modfile() and load_modfile() must stay consistent. What is saved
Expand Down
Loading

0 comments on commit e5217e8

Please sign in to comment.