Skip to content
Snippets Groups Projects
js_file.c 83.3 KiB
Newer Older
rswindell's avatar
rswindell committed
	},
rswindell's avatar
rswindell committed
	{"iniGetValue",		js_iniGetValue,		3,	JSTYPE_UNDEF,	JSDOCSTR("section, key [,default=<i>none</i>]")
rswindell's avatar
rswindell committed
	,JSDOCSTR("parse a key from a <tt>.ini</tt> file and return its value (format = '<tt>key = value</tt>'). "
		"returns the specified <i>default</i> value if the key or value is missing or invalid. "
		"to parse a key from the <i>root</i> section, pass <i>null</i> for <i>section</i>. "
rswindell's avatar
rswindell committed
		"Returns a <i>bool</i>, <i>number</i>, <i>string</i>, or an <i>array of strings</i> "
		"determined by the type of <i>default</i> value specified. "
		"<br><b>Note:</b> To insure that any/all values are returned as a string (e.g. numeric passwords are <b>not</b> returned as a <i>number</i>), "
		"pass an empty string ('') for the <i>default</i> value." )
rswindell's avatar
rswindell committed
	},
rswindell's avatar
rswindell committed
	{"iniSetValue",		js_iniSetValue,		3,	JSTYPE_BOOLEAN,	JSDOCSTR("section, key, [value=<i>none</i>]")
	,JSDOCSTR("set the specified <i>key</i> to the specified <i>value</i> in the specified <i>section</i> "
		"of a <tt>.ini</tt> file. "
		"to set a key in the <i>root</i> section, pass <i>null</i> for <i>section</i>. ")
	{"iniGetObject",	js_iniGetObject,	1,	JSTYPE_OBJECT,	JSDOCSTR("[section=<i>root</i>] [,lowercase=<tt>false</tt>] "
		"[,blanks=<tt>false</tt>]")
rswindell's avatar
rswindell committed
	,JSDOCSTR("parse an entire section from a .ini file "
		"and return all of its keys (optionally lowercased) and values as properties of an object. "
		"If <i>section</i> is <tt>null</tt> or <tt>undefined</tt>, returns keys and values from the <i>root</i> section. "
		"If <i>blanks</i> is <tt>true</tt> then empty string (instead of <tt>undefined</tt>) values may included in the returned object."
rswindell's avatar
rswindell committed
		"Returns <i>null</i> if the specified <i>section</i> does not exist in the file or the file has not been opened.")
rswindell's avatar
rswindell committed
	},
	{"iniSetObject",	js_iniSetObject,	2,	JSTYPE_BOOLEAN,	JSDOCSTR("section, 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. "
		"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." )
	{"iniGetAllObjects",js_iniGetAllObjects,1,	JSTYPE_ARRAY,	JSDOCSTR("[name_property] [,prefix=<i>none</i>] [,lowercase=<tt>false</tt>] "
		"[,blanks=<tt>false</tt>]")
	,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. "
		"<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. "
		"If a (String) <i>prefix</i> is specified, it is removed from each section's name. "
		"If <i>blanks</i> is <tt>true</tt> then empty string (instead of <tt>undefined</tt>) values may be included in the returned objects."
	)
	{"iniSetAllObjects",js_iniSetAllObjects,1,	JSTYPE_BOOLEAN,	JSDOCSTR("object array [,name_property=<tt>\"name\"</tt>]")
	,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>)")
	{"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.")
rswindell's avatar
rswindell committed
	,314
	},
	{"iniRemoveSection",js_iniRemoveSection,1,	JSTYPE_BOOLEAN,	JSDOCSTR("section")
	,JSDOCSTR("remove specified <i>section</i> from <tt>.ini</tt> file.")
rswindell's avatar
rswindell committed
	,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 string (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)
		return;

	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;
deuce's avatar
deuce committed
	if(id != JSID_VOID && id != JSID_EMPTY) {
		jsval idval;
deuce's avatar
deuce committed
		JS_IdToValue(cx, id, &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);
	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");
		return(JS_FALSE);
	}

	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>"
rswindell's avatar
rswindell committed
		"Special features include:</h2><ol 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 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"
rswindell's avatar
rswindell committed
				"</ol>"
			"<li>Support for ASCII text files<ol type=circle>"
				"<li>supports line-based I/O<ol 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 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> formated configuration files<ol type=square>"
					"<li>concept and support of <i>root</i> ini sections added in v3.12"
					"</ol>"
rswindell's avatar
rswindell committed
				"<li>optional ROT13 encoding/translation"
				"</ol>"
			"<li>Dynamically-calculated industry standard checksums (e.g. CRC-16, CRC-32, MD5)"
			"</ol>"
rswindell's avatar
rswindell committed
			);
	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)
	JSObject*	obj;
	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 */
	return(obj);
JSObject* js_CreateFileObject(JSContext* cx, JSObject* parent, char *name, int fd, const char* mode)
{
	JSObject* obj;
	private_t*	p;
deuce's avatar
deuce committed
	int newfd = dup(fd);
	FILE* fp;
deuce's avatar
deuce committed
	if (newfd == -1)
deuce's avatar
deuce committed
	fp = fdopen(newfd, mode);
	if(fp == NULL) {
		close(newfd);
		return NULL;
	}

	obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL
		,JSPROP_ENUMERATE|JSPROP_READONLY);
deuce's avatar
deuce committed
	if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) {
		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 */