Skip to content

Commit

Permalink
add bit offset support (#10)
Browse files Browse the repository at this point in the history
* add bit offset support

* demonstrate different display modes

* add right and left buffer shifts

* update bindings

* add viewport destroy
  • Loading branch information
scholarsmate authored Oct 17, 2021
1 parent 6172d73 commit 570a83a
Show file tree
Hide file tree
Showing 6 changed files with 483 additions and 39 deletions.
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# generate files
# generated files
node_modules/
build/
cmake-build-debug/
cmake-build-*/

# log files
*.log
*.log

# IDE files
.idea/
91 changes: 77 additions & 14 deletions omega_edit/omega_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct viewport_t {
on_change_cbk cbk{};
void *user_data_ptr{};
vector<uint8_t> data;
uint8_t bit_offset{};
};

const author_t *get_viewport_author(const viewport_t *viewport_ptr) {
Expand All @@ -107,20 +108,62 @@ void *get_viewport_user_data(const viewport_t *viewport_ptr) {
return viewport_ptr->user_data_ptr;
}

uint8_t get_viewport_bit_offset(const viewport_t *viewport_ptr) {
return viewport_ptr->bit_offset;
}

typedef vector<shared_ptr<author_t> > author_vector_t;
typedef vector<shared_ptr<viewport_t> > viewport_vector_t;
typedef vector<change_t> change_vector_t;

struct session_t {
FILE *file_ptr{};
int64_t serial{};
int64_t computed_file_size{};
vector<shared_ptr<author_t> > authors;
vector<shared_ptr<viewport_t> > viewports;
vector<change_t> changes;
author_vector_t authors;
viewport_vector_t viewports;
change_vector_t changes;
vector<int64_t> changes_by_offset;
};

//
// FUNCTIONS
//

int left_shift_buffer(uint8_t *array, int64_t len, uint8_t shift_left) {
int rc = -1;
if (shift_left > 0 && shift_left < 8) {
uint8_t shift_right = 8 - shift_left;
uint8_t mask = ((1 << shift_left) - 1) << shift_right;
uint8_t bits1 = 0;
for (auto i = len - 1; i >= 0; --i) {
auto bits2 = array[i] & mask;
array[i] <<= shift_left;
array[i] |= bits1 >> shift_right;
bits1 = bits2;
}
rc = 0;
}
return rc;
}

int right_shift_buffer(uint8_t *array, int64_t len, uint8_t shift_right) {
int rc = -1;
if (shift_right > 0 && shift_right < 8) {
uint8_t shift_left = 8 - shift_right;
uint8_t mask = (1 << shift_right) - 1;
uint8_t bits1 = 0;
for (auto i = len - 1; i >= 0; --i) {
auto bits2 = array[i] & mask;
array[i] >>= shift_right;
array[i] |= bits1 << shift_left;
bits1 = bits2;
}
rc = 0;
}
return rc;
}

session_t *create_session(FILE *file_ptr) {
fseek(file_ptr, 0L, SEEK_END);
auto *session_ptr = new session_t;
Expand All @@ -147,7 +190,8 @@ session_t *get_author_session(const author_t *author_ptr) {
}

viewport_t *
add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr) {
add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr,
uint8_t bit_offset) {
auto viewport_ptr = shared_ptr<viewport_t>(new viewport_t);
viewport_ptr->author_ptr = author_ptr;
viewport_ptr->computed_offset = offset;
Expand All @@ -156,31 +200,52 @@ add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_ch
viewport_ptr->data.reserve(capacity);
viewport_ptr->cbk = cbk;
viewport_ptr->user_data_ptr = user_data_ptr;
viewport_ptr->bit_offset = bit_offset;
author_ptr->session_ptr->viewports.push_back(viewport_ptr);
// TODO: populate the viewport and call the on change callback
read_segment(author_ptr->session_ptr->file_ptr, offset, author_ptr->session_ptr->computed_file_size,
viewport_ptr->data.data(), viewport_ptr->capacity,
&viewport_ptr->length);
&viewport_ptr->length, viewport_ptr->bit_offset);
(*viewport_ptr->cbk)(viewport_ptr.get(), nullptr);
return viewport_ptr.get();
}

int set_viewport(viewport_t *viewport_ptr, int64_t offset, int32_t capacity) {
int destroy_viewport(const viewport_t *viewport_ptr) {
int rc = -1;
viewport_vector_t *session_viewport_ptr = &viewport_ptr->author_ptr->session_ptr->viewports;
for (auto iter = session_viewport_ptr->begin(); iter != session_viewport_ptr->end(); ++iter) {
if (viewport_ptr == iter->get()) {
session_viewport_ptr->erase(iter);
rc = 0;
break;
}
}
return rc;
}

int set_viewport(viewport_t *viewport_ptr, int64_t offset, int32_t capacity, uint8_t bit_offset) {
// only change settings if they are different
if (viewport_ptr->computed_offset != offset || viewport_ptr->capacity != capacity) {
if (viewport_ptr->computed_offset != offset || viewport_ptr->capacity != capacity ||
viewport_ptr->bit_offset != bit_offset) {
viewport_ptr->computed_offset = offset;
viewport_ptr->capacity = capacity;
viewport_ptr->data.reserve(capacity);
viewport_ptr->bit_offset = bit_offset;
// TODO: update viewport and call the on change callback
read_segment(viewport_ptr->author_ptr->session_ptr->file_ptr, offset,
viewport_ptr->author_ptr->session_ptr->computed_file_size, viewport_ptr->data.data(),
viewport_ptr->capacity,
&viewport_ptr->length);
&viewport_ptr->length,
viewport_ptr->bit_offset);
(*viewport_ptr->cbk)(viewport_ptr, nullptr);
}
return 0;
}

size_t num_viewports(const session_t *session_ptr) {
return session_ptr->viewports.size();
}

// Internal function to add a change to the given session
int add_change_(const change_t *change_ptr) {
auto session_ptr = change_ptr->author_ptr->session_ptr;
Expand Down Expand Up @@ -286,12 +351,15 @@ size_t num_changes_by_author(const author_t *author_ptr) {
}

int read_segment(FILE *from_file_ptr, int64_t offset, int64_t file_size, uint8_t *buffer, int64_t capacity,
int64_t *length) {
int64_t *length, uint8_t bit_offset) {
auto len = file_size - offset;
if (len > 0) {
*length = (len < capacity) ? len : capacity;
fseek(from_file_ptr, offset, SEEK_SET);
fread(buffer, 1, *length, from_file_ptr);
if (bit_offset > 0) {
left_shift_buffer(buffer, *length, bit_offset);
}
}
return 0;
}
Expand Down Expand Up @@ -368,11 +436,6 @@ int save(const author_t *author_ptr, FILE *file_ptr) {
return 0;
}

viewport_t *add_viewport(const author_t *author_ptr, int32_t capacity, on_change_cbk cbk, void *user_data_ptr) {
// TODO: Implement
return nullptr;
}

// returns 1 if a change was found and undone and 0 if no change was found
int undo(const author_t *author_ptr) {
int rc = 0;
Expand Down
18 changes: 15 additions & 3 deletions omega_edit/omega_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const uint8_t *get_viewport_data(const viewport_t *viewport_ptr);

void *get_viewport_user_data(const viewport_t *viewport_ptr);

uint8_t get_viewport_bit_offset(const viewport_t *viewport_ptr);

// Returns the author's name from the given author structure
const char *get_author_name(const author_t *author_ptr);

Expand All @@ -63,7 +65,10 @@ const author_t *add_author(session_t *session_ptr, const char *author_name);

// Add a viewport to the given session
viewport_t *
add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr);
add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr,
uint8_t bit_offset);

int destroy_viewport(const viewport_t *viewport_ptr);

// Destroy the given session
void destroy_session(session_t *session_ptr);
Expand All @@ -86,7 +91,10 @@ int64_t offset_to_computed_offset(const session_t *session_ptr, int64_t offset);
int64_t computed_offset_to_offset(const session_t *session_ptr, int64_t offset);

// Set viewport at the given offset (return 0 on success, non-zero otherwise)
int set_viewport(viewport_t *viewport_ptr, int64_t offset, int32_t capacity);
int set_viewport(viewport_t *viewport_ptr, int64_t offset, int32_t capacity, uint8_t bit_offset);

// Number of active viewports in this given session
size_t num_viewports(const session_t *session_ptr);

// Undo the last change for this author from the given session (return 0 on success, non-zero otherwise)
int undo(const author_t *author_ptr);
Expand All @@ -95,8 +103,12 @@ int undo(const author_t *author_ptr);
int save(const author_t *author_ptr, FILE *file_ptr);

int read_segment(FILE *from_file_ptr, int64_t offset, int64_t file_size, uint8_t *buffer, int64_t capacity,
int64_t *length);
int64_t *length, uint8_t bit_offset);

int write_segment(FILE *from_file_ptr, int64_t offset, int64_t byte_count, FILE *to_file_ptr);

int left_shift_buffer(uint8_t *array, int64_t len, uint8_t shift_left);

int right_shift_buffer(uint8_t *array, int64_t len, uint8_t shift_right);

#endif //OMEGA_OMEGA_EDIT_H
Loading

0 comments on commit 570a83a

Please sign in to comment.