Skip to content
Snippets Groups Projects
js_file.c 87.9 KiB
Newer Older
		        "Returns <i>null</i> if the specified <i>section</i> does not exist in the file or the file has not been opened.")
	 , 311},
	{"iniSetObject",    js_iniSetObject,    2,  JSTYPE_BOOLEAN, JSDOCSTR("section, <i>object</i> object")
	 , JSDOCSTR("Write all the properties of the specified <i>object</i> as separate <tt>key=value</tt> pairs "
		        "in the specified <i>section</i> of a <tt>.ini</tt> file.<br>"
		        "To write an object in the <i>root</i> section, pass <i>null</i> for <i>section</i>."
		        "<br><b>Note:</b> this method does not remove unreferenced keys from an existing section. "
		        "If your intention is to <i>replace</i> an existing section, use the <tt>iniRemoveSection</tt> function first." )
	 , 312},
	{"iniGetAllObjects", js_iniGetAllObjects, 1,  JSTYPE_ARRAY,   JSDOCSTR("[<i>string</i> name_property] [,<i>bool</i> prefix=<i>none</i>] [,<i>bool</i> lowercase=false] "
		                                                                   "[,blanks=false]")
	 , JSDOCSTR("Parse all sections from a .ini file and return all (non-<i>root</i>) sections "
		        "in an array of objects with each section's keys (optionally lowercased) as properties of each object.<br>"
		        "<i>name_property</i> is the name of the property to create to contain the section's name "
		        "(optionally lowercased, default is <tt>\"name\"</tt>), "
		        "the optional <i>prefix</i> has the same use as in the <tt>iniGetSections</tt> method.<br>"
		        "If a (String) <i>prefix</i> is specified, it is removed from each section's name.<br>"
		        "If <i>blanks</i> is <tt>true</tt> then empty string (instead of <tt>undefined</tt>) values may be included in the returned objects."
		        )
	 , 311},
	{"iniSetAllObjects", js_iniSetAllObjects, 1,  JSTYPE_BOOLEAN, JSDOCSTR("<i>object</i> array [,name_property=\"name\"]")
	 , JSDOCSTR("Write an array of objects to a .ini file, each object in its own section named "
		        "after the object's <i>name_property</i> (default: <tt>name</tt>)")
	 , 312},
	{"iniRemoveKey",    js_iniRemoveKey,    2,  JSTYPE_BOOLEAN, JSDOCSTR("section, key")
	 , JSDOCSTR("Remove specified <i>key</i> from specified <i>section</i> in <tt>.ini</tt> file.")
	 , 314},
	{"iniRemoveSection", js_iniRemoveSection, 1,  JSTYPE_BOOLEAN, JSDOCSTR("section")
	 , JSDOCSTR("Remove specified <i>section</i> from <tt>.ini</tt> file.")
	 , 314},
	{"iniRemoveSections", js_iniRemoveSections, 1, JSTYPE_BOOLEAN,    JSDOCSTR("[prefix]")
	 , JSDOCSTR("Remove all sections from <tt>.ini</tt> file, optionally only sections with the specified section name <i>prefix</i>.")
	 , 32000},
	{"iniReadAll",      js_iniReadAll,      0,  JSTYPE_ARRAY,   JSDOCSTR("")
	 , JSDOCSTR("Read entire <tt>.ini</tt> file into an array of strings (with <tt>!include</tt>ed files).")
	 , 31802},
/* File Destructor */

static void js_finalize_file(JSContext *cx, JSObject *obj)
{
	private_t* p;
	if ((p = (private_t*)JS_GetPrivate(cx, obj)) == NULL)
	dbprintf(FALSE, p, "finalized: %s", p->name);
	FREE_AND_NULL(p->ini_style.key_prefix);
	FREE_AND_NULL(p->ini_style.section_separator);
	FREE_AND_NULL(p->ini_style.value_separator);
	FREE_AND_NULL(p->ini_style.bit_separator);
	FREE_AND_NULL(p->ini_style.literal_separator);
static JSBool js_file_resolve(JSContext *cx, JSObject *obj, jsid id)
	char*  name = NULL;
	JSBool ret;
	if (id != JSID_VOID && id != JSID_EMPTY) {
deuce's avatar
deuce committed
		jsval idval;
deuce's avatar
deuce committed
		JS_IdToValue(cx, id, &idval);
		if (JSVAL_IS_STRING(idval))
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL);
deuce's avatar
deuce committed
	}
	ret = js_SyncResolve(cx, obj, name, js_file_properties, js_file_functions, NULL, 0);
	if (name)
		free(name);
	return ret;
}

static JSBool js_file_enumerate(JSContext *cx, JSObject *obj)
{
deuce's avatar
deuce committed
	return(js_file_resolve(cx, obj, JSID_VOID));
	"File"                  /* name			*/
	, JSCLASS_HAS_PRIVATE    /* flags		*/
	, JS_PropertyStub        /* addProperty	*/
	, JS_PropertyStub        /* delProperty	*/
	, js_file_get            /* getProperty	*/
	, js_file_set            /* setProperty	*/
	, js_file_enumerate      /* enumerate	*/
	, js_file_resolve        /* resolve		*/
	, JS_ConvertStub         /* convert		*/
	, js_finalize_file       /* finalize		*/
};

/* File Constructor (creates file descriptor) */

static JSBool
js_file_constructor(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	JSString*  str;
	private_t* p;
	obj = JS_NewObject(cx, &js_file_class, NULL, NULL);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
	if (argc < 1 || (str = JS_ValueToString(cx, argv[0])) == NULL) {
		JS_ReportError(cx, "No filename specified");
	if ((p = (private_t*)calloc(1, sizeof(private_t))) == NULL) {
		JS_ReportError(cx, "calloc failed");
	JSSTRING_TO_STRBUF(cx, str, p->name, sizeof(p->name), NULL);
	if (!JS_SetPrivate(cx, obj, p)) {
		dbprintf(TRUE, p, "JS_SetPrivate failed");
		return(JS_FALSE);
	}

	js_DescribeSyncObject(cx, obj, "Class used for opening, creating, reading, or writing files on the local file system<p>"
	                      "Special features include:</h2><ol style=list-style-type:disc>"
	                      "<li>Exclusive-access files (default) or shared files<ol type=circle>"
	                      "<li>optional record-locking"
	                      "<li>buffered or non-buffered I/O"
	                      "</ol>"
	                      "<li>Support for binary files<ol style=list-style-type:circle>"
	                      "<li>native or network byte order (endian)"
	                      "<li>automatic Unix-to-Unix (<i>UUE</i>), yEncode (<i>yEnc</i>) or Base64 encoding/decoding"
	                      "</ol>"
	                      "<li>Support for ASCII text files<ol style=list-style-type:circle>"
	                      "<li>supports line-based I/O<ol style=list-style-type:square>"
	                      "<li>entire file may be read or written as an array of strings"
	                      "<li>individual lines may be read or written one line at a time"
	                      "</ol>"
	                      "<li>supports fixed-length records<ol style=list-style-type:square>"
	                      "<li>optional end-of-text (<i>etx</i>) character for automatic record padding/termination"
	                      "<li>Synchronet <tt>.dat</tt> files use an <i>etx</i> value of 3 (Ctrl-C)"
	                      "</ol>"
	                      "<li>supports <tt>.ini</tt> formatted configuration files"
	                      "</ol>"
	                      "<li>Dynamically-calculated industry standard checksums (e.g. CRC-16, CRC-32, MD5)"
	                      "</ol>"
	                      , 310
	                      );
	js_DescribeSyncConstructor(cx, obj, "To create a new File object: <tt>var f = new File(<i>filename</i>)</tt>");
	js_CreateArrayOfStrings(cx, obj, "_property_desc_list", file_prop_desc, JSPROP_READONLY);
#endif

	dbprintf(FALSE, p, "object constructed");
	return(JS_TRUE);
}
JSObject* js_CreateFileClass(JSContext* cx, JSObject* parent)
	obj = JS_InitClass(cx, parent, NULL
	                   , &js_file_class
	                   , js_file_constructor
	                   , 1 /* number of constructor args */
	                   , NULL /* props, set in constructor */
	                   , NULL /* funcs, set in constructor */
	                   , NULL, NULL);
	return(obj);
JSObject* js_CreateFileObject(JSContext* cx, JSObject* parent, char *name, int fd, const char* mode)
	JSObject*  obj;
	private_t* p;
	int        newfd = dup(fd);
	FILE*      fp;
deuce's avatar
deuce committed
	if (newfd == -1)
deuce's avatar
deuce committed
	fp = fdopen(newfd, mode);
deuce's avatar
deuce committed
		close(newfd);
		return NULL;
	}

	obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL
	                      , JSPROP_ENUMERATE | JSPROP_READONLY);
	if ((p = (private_t*)calloc(1, sizeof(private_t))) == NULL) {
deuce's avatar
deuce committed
		fclose(fp);
deuce's avatar
deuce committed
	}
	p->fp = fp;
	p->debug = JS_FALSE;
	if (!JS_SetPrivate(cx, obj, p)) {
		dbprintf(TRUE, p, "JS_SetPrivate failed");
		return(NULL);
	}
	dbprintf(FALSE, p, "object created");

	return(obj);
}


#endif  /* JAVSCRIPT */