Skip to content

Commit 7d59a52

Browse files
committed
refactor(buffer): embed provider in Buffer class with Notebook pointer
Refactor Buffer to hold a direct Notebook* pointer (non-owning) and embed IBufferProvider via factory pattern. BufferManager now resolves notebook before creating Buffer, and restores buffer IDs from session config. - Convert Buffer from struct to class with proper encapsulation - Add CreateProvider() factory: StandardBufferProvider for bundled, ExternalBufferProvider for external files, none for raw notebooks - Add SetId() as private friend method for BufferManager session restore - Remove separate providers_ map from BufferManager - Fix buffer ID persistence bug in LoadBuffers() - Fix .clang-format to enforce right-aligned pointers/references
1 parent f75e29b commit 7d59a52

16 files changed

+2364
-169
lines changed

.clang-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Language: Cpp
44
Standard: Latest
55
ColumnLimit: 100
66
IndentWidth: 2
7+
DerivePointerAlignment: false
78
PointerAlignment: Right
89
ReferenceAlignment: Pointer
910
...

include/vxcore/vxcore.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,113 @@ VXCORE_API VxCoreError vxcore_buffer_auto_save_tick(VxCoreContextHandle context)
417417
VXCORE_API VxCoreError vxcore_buffer_set_auto_save_interval(VxCoreContextHandle context,
418418
int64_t interval_ms);
419419

420+
// ============ Buffer Asset Operations (Filesystem Only) ============
421+
// Asset operations only touch the filesystem, they do NOT modify attachment metadata.
422+
// Use these for embedding inline content (images, diagrams) that don't need tracking.
423+
424+
// Insert binary data as an asset file (NO attachment tracking).
425+
// Creates assets folder lazily if it doesn't exist.
426+
// If asset_name already exists, a unique name is generated (e.g., image_1.png).
427+
//
428+
// buffer_id: ID of an open buffer
429+
// asset_name: Desired filename (e.g., "screenshot.png")
430+
// data: Binary content to write
431+
// data_size: Size of data in bytes
432+
// out_relative_path: Receives the relative path for embedding in content
433+
// (e.g., "vx_assets/<uuid>/screenshot.png" for notebook files,
434+
// or "<filename>_assets/screenshot.png" for external files)
435+
// Caller must free with vxcore_string_free.
436+
// Returns VXCORE_ERR_BUFFER_NOT_FOUND if buffer doesn't exist.
437+
// Returns VXCORE_ERR_UNSUPPORTED for raw notebooks.
438+
// Returns VXCORE_ERR_IO on filesystem error.
439+
VXCORE_API VxCoreError vxcore_buffer_insert_asset_raw(VxCoreContextHandle context,
440+
const char *buffer_id, const char *asset_name,
441+
const void *data, size_t data_size,
442+
char **out_relative_path);
443+
444+
// Copy a file to assets folder (NO attachment tracking).
445+
// Creates assets folder lazily if it doesn't exist.
446+
// If filename already exists, a unique name is generated.
447+
//
448+
// source_path: Absolute path to source file
449+
// out_relative_path: Receives the relative path for embedding in content
450+
// Caller must free with vxcore_string_free.
451+
VXCORE_API VxCoreError vxcore_buffer_insert_asset(VxCoreContextHandle context,
452+
const char *buffer_id, const char *source_path,
453+
char **out_relative_path);
454+
455+
// Delete an asset file from the buffer's assets folder (NO attachment tracking).
456+
// Does NOT touch attachment metadata.
457+
//
458+
// relative_path: Path as returned by vxcore_buffer_insert_asset*
459+
// Returns VXCORE_ERR_NOT_FOUND if asset doesn't exist.
460+
VXCORE_API VxCoreError vxcore_buffer_delete_asset(VxCoreContextHandle context,
461+
const char *buffer_id, const char *relative_path);
462+
463+
// Get absolute path to the buffer's assets folder.
464+
// Creates folder lazily if it doesn't exist.
465+
//
466+
// out_path: Receives absolute filesystem path.
467+
// Caller must free with vxcore_string_free.
468+
VXCORE_API VxCoreError vxcore_buffer_get_assets_folder(VxCoreContextHandle context,
469+
const char *buffer_id, char **out_path);
470+
471+
// ============ Buffer Attachment Operations (Filesystem + Metadata) ============
472+
// Attachment operations modify both filesystem and attachment metadata.
473+
// Use these for files that need to be tracked (downloadable attachments).
474+
475+
// Copy a file to attachments folder and add to attachment list.
476+
// For notebook files: copies file + adds to FileRecord.attachments
477+
// For external files: copies file only (no metadata tracking available)
478+
//
479+
// source_path: Absolute path to source file
480+
// out_filename: Receives just the filename (not full path)
481+
// Caller must free with vxcore_string_free.
482+
VXCORE_API VxCoreError vxcore_buffer_insert_attachment(VxCoreContextHandle context,
483+
const char *buffer_id,
484+
const char *source_path,
485+
char **out_filename);
486+
487+
// Delete an attachment file and remove from attachment list.
488+
//
489+
// filename: Just the filename (not full path)
490+
// Returns VXCORE_ERR_NOT_FOUND if attachment doesn't exist.
491+
VXCORE_API VxCoreError vxcore_buffer_delete_attachment(VxCoreContextHandle context,
492+
const char *buffer_id, const char *filename);
493+
494+
// Rename an attachment file and update attachment list.
495+
// If new_filename already exists, a unique name is generated.
496+
//
497+
// old_filename: Current filename
498+
// new_filename: New filename
499+
// out_new_filename: Receives the actual new filename (may differ if collision)
500+
// Caller must free with vxcore_string_free.
501+
VXCORE_API VxCoreError vxcore_buffer_rename_attachment(VxCoreContextHandle context,
502+
const char *buffer_id,
503+
const char *old_filename,
504+
const char *new_filename,
505+
char **out_new_filename);
506+
507+
// List all attachments (from metadata, not filesystem scan).
508+
// For notebook files: returns FileRecord.attachments
509+
// For external files: returns filesystem listing (no metadata)
510+
// Returns JSON array of filenames (not full paths).
511+
//
512+
// out_attachments_json: Receives JSON array (e.g., ["doc.pdf", "data.zip", ...])
513+
// Caller must free with vxcore_string_free.
514+
VXCORE_API VxCoreError vxcore_buffer_list_attachments(VxCoreContextHandle context,
515+
const char *buffer_id,
516+
char **out_attachments_json);
517+
518+
// Get absolute path to the buffer's attachments folder.
519+
// Creates folder lazily if it doesn't exist.
520+
// (Same folder as assets folder - attachments and assets share location)
521+
//
522+
// out_path: Receives absolute filesystem path.
523+
// Caller must free with vxcore_string_free.
524+
VXCORE_API VxCoreError vxcore_buffer_get_attachments_folder(VxCoreContextHandle context,
525+
const char *buffer_id, char **out_path);
526+
420527
VXCORE_API void vxcore_string_free(char *str);
421528

422529
#ifdef __cplusplus

src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ set(VXCORE_SOURCES
2626
core/workspace_manager.cpp
2727
core/buffer.cpp
2828
core/buffer_manager.cpp
29+
core/buffer_provider.cpp
30+
core/standard_buffer_provider.cpp
31+
core/external_buffer_provider.cpp
2932
core/notebook.cpp
3033
core/bundled_notebook.cpp
3134
core/raw_notebook.cpp

0 commit comments

Comments
 (0)