8 poin oleh GN⁺ 2025-09-22 | 1 komentar | Bagikan ke WhatsApp
  • Sj.h adalah parser JSON ultra-ringan yang terdiri dari sekitar 150 baris dan dapat digunakan di lingkungan berbasis C99
  • Memiliki karakteristik seperti tanpa alokasi memori dan state minimal, sehingga cocok untuk lingkungan embedded yang ringan atau saat ingin meminimalkan dependensi
  • Mengadopsi pendekatan yang menangani parsing angka dan string secara langsung, sehingga pengguna dapat dengan bebas mengimplementasikan pemrosesan terkait
  • Mendukung pesan kesalahan berbasis baris:kolom, sehingga keterbacaan saat debugging dan identifikasi lokasi menjadi lebih baik
  • Sebagai perangkat lunak domain publik, siapa pun bebas menggunakan, mengubah, dan mendistribusikannya

Pengenalan proyek

  • Sj.h adalah file header C99 yang menyediakan kemampuan parsing JSON hanya dengan kode seminimal mungkin, tanpa fitur berlebihan atau alokasi memori yang tidak perlu
  • Seluruh implementasinya sekitar 150 baris, sehingga cocok untuk sistem embedded, alat bantu, atau ketika ingin mengurangi ketergantungan pada pustaka eksternal

Fitur utama

  • Berjalan dengan zero-allocations dan minimal state, sehingga beban memori sangat rendah
  • Dengan pesan kesalahan yang menyertakan informasi baris:kolom, lokasi masalah yang terjadi selama parsing mudah diidentifikasi
  • Parsing angka tidak disediakan secara bawaan; pengguna dapat memakai cara yang diinginkan seperti strtod, atoi
  • Parsing string juga dapat diimplementasikan sendiri, atau penanganan Unicode surrogate pair dapat dibangun sesuai kebutuhan
  • Seluruh kode sumber disediakan sebagai domain publik (Unlicense), sehingga dapat digunakan dan diubah tanpa batasan lisensi

Contoh penggunaan

  • Disediakan contoh sederhana untuk mem-parsing string JSON menjadi struct Rect
    char *json_text = "{ \"x\": 10, \"y\": 20, \"w\": 30, \"h\": 40 }";  
    typedef struct { int x, y, w, h; } Rect;  
    ...  
    
  • Menggunakan API yang sederhana dan jelas seperti sj_Reader, sj_Value, sj_reader, sj_read, sj_iter_object
  • Parsing nilai numerik maupun perbandingan key-value diimplementasikan sendiri (tidak disediakan builtin)
  • Berbagai contoh penggunaan tambahan dapat dilihat di folder demo

Lisensi

  • Sj.h adalah perangkat lunak domain publik yang dapat digunakan siapa saja tanpa batasan
  • Untuk detail lebih lanjut, lihat file LICENSE

Lainnya

  • Karena kode dan struktur foldernya sederhana, ini bisa langsung digunakan tanpa konfigurasi atau prosedur build terpisah
  • Bersifat mandiri, tidak memiliki dependensi eksternal, dan terutama cocok untuk lingkungan yang membutuhkan keringanan serta kemudahan penggunaan

1 komentar

 
GN⁺ 2025-09-22
Komentar Hacker News
  • Alasan saya menyukai karya penulis ini adalah karena kebanyakan berupa pustaka satu berkas yang ditulis dalam ANSI C atau Lua, fokus pada cakupan yang jelas, menyediakan antarmuka yang mudah digunakan dan dokumentasi yang sangat baik, dan saya juga menyukai lisensi perangkat lunak bebasnya. Selain proyek ini, ada beberapa karya lain yang saya sukai: log.c (pustaka logging C99 yang simpel), microui (pustaka UI immediate-mode yang sangat kecil), fe (bahasa kecil yang bisa di-embed), microtar (pustaka tar ringan), cembed (alat untuk meng-embed berkas ke header C), ini (pustaka ringan untuk berkas konfigurasi .ini), json.lua (pustaka JSON ringan untuk Lua), lite (editor teks ringan yang dibuat dengan Lua), cmixer (audio mixer portabel untuk game), dan uuid4 (pustaka uuid4 kecil yang diimplementasikan dalam C)
    • Saya selalu membawa log.c ke setiap proyek C yang saya kerjakan. Saya tidak tahu penulis ini membuat begitu banyak pustaka; log.c benar-benar mudah dipakai, jadi saya bisa merekomendasikannya
    • Saya pernah memakai pustaka Lume saat membuat game dengan LOVE2D, dan saya juga pernah beberapa kali bertemu penulisnya di ruang obrolan IRC. Suatu kali saya pernah bilang idenya buruk, tapi setelah dipikir lagi ternyata itu ide yang bagus. https://github.com/rxi/lume layak dilihat
    • Ini memang open source, tapi bukan free software dalam arti yang sesungguhnya
  • Pustaka ini tidak melakukan pengecekan signed integer overflow pada baris-baris berikut: L89, L149, L150. Bergantung pada nilai input tertentu, undefined behavior bisa terjadi
    • Sebagian pengembang menikmati budaya pustaka C satu header yang sederhana; streamer seperti Tsoding adalah contoh yang mewakili. Mereka paham bahwa pustaka semacam ini tidak berfokus pada keamanan atau kelengkapan fitur. Tidak semua proyek adalah perangkat lunak kelas bisnis yang terekspos ke banyak pelanggan, jadi pendekatan seperti ini juga tidak masalah
    • Ada artikel yang bagus tentang membengkaknya pustaka yang menangani semua edge case, dan ada juga diskusi terkait. Jika mencoba menangani semua error, kompleksitasnya melonjak tajam, dan terkadang itu juga bukan tanggung jawab pustaka
    • UB bisa terjadi hanya jika kedalaman level melebihi 2 miliar, atau pada kasus kedua jika jumlah baris melebihi 2 miliar. Jika input JS dibatasi ke 1GB, maka kalau lebih dari itu bagian lain dari stack akan lebih dulu mengalami masalah yang lebih besar. Jika saya harus memproses JSON lebih dari 2GB, saya akan mengganti semua int di source code menjadi 64-bit. Meski begitu, kalau inputnya melebihi 2^64, pada akhirnya tetap akan mati. Saya juga tidak berniat mengecek overflow int satu per satu di kode
    • Karena int berukuran 32-bit, masalah baru muncul jika setiap baris memiliki nesting sedalam 2 miliar, atau berkas memiliki lebih dari 2 miliar baris, atau satu baris memiliki lebih dari 2 miliar karakter
    • Sepertinya pustaka ini tidak akan bisa dipakai di production
  • Pustaka ini cukup permisif. Saya tidak bisa bilang pendekatan seperti ini buruk, tapi orang yang memakainya tanpa melihat kodenya perlu berhati-hati. Inilah alasan utama mengapa kodenya bisa sekecil ini. Jika melihat contoh demo di README, ia berperilaku seperti ini:<br><code>{"x",10eee"y"22:5,{[:::,,}]"w"7"h"33<br>rect: { 10, 22, 7, 33 }</code>
    • Parser ini pada umumnya mengasumsikan inputnya valid. Pekerjaan validasi adalah masalah yang sepenuhnya terpisah dan tidak dicakup oleh pustaka ini. Pada akhirnya pustaka ini berperan untuk mengekstrak data
    • Jadi itu salah?
  • Menurut saya pustaka parser JSON secara umum adalah lubang hitam penderitaan; masing-masing ditujukan ke tempat penggunaan yang berbeda, dan sering kali dipenuhi abstraksi yang rumit, atau bahkan keduanya sekaligus. Sebenarnya ini bukan masalah yang terlalu sulit jika Anda hanya mengimplementasikan bagian yang benar-benar dibutuhkan untuk tujuan tertentu
    • Mengejutkan melihat betapa rumitnya pustaka JSON modern. Dulu pustaka JSON C++ satu header milik nlohmann benar-benar sederhana, tapi sekarang<br>* sudah berumur 13 tahun<br>* pull request masih aktif di-merge<br>* memiliki 122 juta unit test<br>meski begitu mereka sendiri mengakui itu bukan yang tercepat. Jika benar-benar butuh kecepatan, mereka menyarankan simdjson. Sebaiknya jangan berniat membuat pustaka parser JSON sendiri; 90% pertama bisa ditulis dalam 45 menit, tapi 10% sisanya bisa menghabiskan ribuan jam kerja dari sepuluh ribu orang
    • Ada referensi terkenal berjudul Parsing JSON is a Minefield (2016) https://seriot.ch/projects/parsing_json.html
    • Desain yang senetral pustaka ini juga rasanya jarang. Ia hanya mengembalikan key dan item array secara berulang, lalu membedakan tipe melalui string-slice yang dikembalikan
    • Proyek ini menonjolkan zero-allocation dan penyimpanan state seminimal mungkin, tetapi pada tipe yang paling umum dipakai seperti string pada akhirnya alokasi tetap diperlukan. Ini adalah alternatif yang sangat berbeda dari masalah yang saya hadapi
    • Saya masih berharap S-Expressions tetap dicintai
  • Menarik, tapi saya penasaran seberapa banyak conformance test yang bisa dilewati pustaka ini https://github.com/nst/JSONTestSuite
    • Dari sisi validasi, pustaka ini tampaknya tidak terlalu ketat. Misalnya, ia menerima objek atau array yang ditutup dengan ] maupun }, dan juga menganggap \v sebagai whitespace, jadi lebih permisif daripada standar. Lebih tepat jika dipandang sebagai "ekstraktor data untuk JSON yang benar". Meski begitu, menulis parser string atau angka sendiri bisa merepotkan, terutama jika perlu menyepakati subset sintaks JSON dengan pihak yang menghasilkan datanya
    • Akan sangat berguna jika ada conformance test yang dibuat berdasarkan implementasi nyata: test-set yang persis sesuai dengan subset/superset dari perilaku pustaka parser tertentu. Dengan begitu, kita bisa menghindari risiko kerentanan akibat dua parser menafsirkan JSON yang sama secara berbeda, misalnya bypass autentikasi
    • Ini pertanyaan sungguhan, apakah nested object didukung?
  • Ini terlihat seperti parser yang setengah jadi; karena angka tidak dikonversi ke float atau int, sepertinya Anda harus menambahkan bagian seperti itu sendiri. Meski begitu tetap mengesankan dan saya bersedia memakainya, saya cuma ingin menyoroti hal itu
  • Saya penasaran apakah C99 memang menyatakan struct ini diinisialisasi ke 0 secara default, atau sebenarnya = { 0 } yang terlewat. Jika melihat kode terkait, r->depth tampaknya belum diinisialisasi dan bisa saja kebetulan sama dengan depth di loop sj__discard_until
    • r->depth sebenarnya sudah diinisialisasi ke 0 di sini, lihat kode terkait
  • Saya penasaran apa tujuan penggunaan pustaka seperti ini, padahal tampaknya sudah ada banyak pustaka JSON yang sangat baik. Apakah ini alat edukasi?
    • Mudah diintegrasikan ke codebase yang sudah ada, jejak ukurannya kecil, tidak memakai alokasi heap, dan juga tidak memakai stdlib (hanya menyertakan stdbool.h dan stddef.h untuk definisi tipe). Tidak ada permainan template C++, dan API-nya intuitif. Sangat jarang ada pustaka C yang memenuhi semua syarat ini; di C++ malah lebih jarang lagi
    • Parsing tanpa overhead dan tanpa alokasi itu menarik. Berguna saat ingin mengekstrak properti tertentu dari dump json berukuran besar, misalnya dump Wikidata
    • Bisa langsung dipakai di CPU embedded, bahkan sekarang sepertinya server API pun bisa dijalankan di perangkat seperti vape
    • Karena kodenya kecil, peninjauan untuk proyek dengan persyaratan keamanan ketat juga lebih mudah, dan kepatuhan lisensinya sangat sederhana (tidak perlu teks pemberitahuan)
    • Ini bisa menjadi codebase yang bagus untuk referensi pemula atau bagi orang yang ingin melakukan parsing sederhana. Berguna saat memerlukan code footprint kecil dalam proyek hobi berskala kecil dengan prosesor terbatas. Meski begitu, untuk kasus seperti itu saya mungkin akan lebih memilih format berkas seperti TOML
  • Keren! Kalau nanti saya butuh parser JSON dalam C, saya akan mempertimbangkan untuk melihat ini. Selama bertahun-tahun saya sudah cocok memakai cJSON (https://github.com/DaveGamble/cJSON); sebelumnya saya pernah memakai wjelement (https://github.com/netmail-open/wjelement), tapi akhirnya pindah karena beberapa masalah (alasan spesifiknya sudah terlalu lama jadi saya lupa)
  • Rasanya agak dipaksakan menyebut ini parser; secara umum ini tampak lebih dekat ke lexer