rev 639 - trunk/src

SVN User <[email protected]> Fri, 18 Jun 2004 23:10:12 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-18 23:10:09 -0400 (Fri, 18 Jun 2004)
New Revision: 639

Modified:
   trunk/src/builtins-file.c
   trunk/src/object.h
Log:
finished TextFile (untested)

Modified: trunk/src/builtins-file.c
===================================================================
--- trunk/src/builtins-file.c	2004-06-19 01:41:25 UTC (rev 638)
+++ trunk/src/builtins-file.c	2004-06-19 03:10:09 UTC (rev 639)
@@ -1311,18 +1311,16 @@
 	INT_32_PARAM(5, bufsize);
 
 	read_unlock(ist, self);
-
 	set_attr(ist, self, sym(ist, "encoding"), NEW_STRING(encoding));
 	if (magic) set_attr(ist, self, sym(ist, "magic"), OBJ(PR_TRUE));
-
 	if (strlen(mode) == 0) {
-		read_unlock(ist, self);
 		SET_TYPE_IF_EXC(TextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 		set_file_obj_data(ist, self, parms[1], NULL, NULL, 0, 0);
 		read_lock(ist, self);
 		self->unclonable = TRUE;
 		return OBJ(NONE);
 	}
+	read_lock(ist, self);
 
 	if ((mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') ||
 	    (mode[1] != '+' && mode[1] != '\0')) {
@@ -1364,7 +1362,74 @@
 	self->unclonable = TRUE;
 	return OBJ(NONE);
 }
+DEF(TextFile, open, FPARM4( mode,		NEW_STRING("r"),
+							encoding,	NEW_STRING("ASCII"),
+							magic,		OBJ(PR_FALSE),
+                            bufsize,	NEW_INT(-1)   ) ) {
+	apr_file_t *f;
+	apr_status_t aprerr;
+	apr_int32_t flags = 0;
+	char err_buf[1024];
+	char *path, *mode, *encoding;
+	int magic, bufsize;
+	file_p filep;
 
+	BIN_CONTENT_CHK(TextFile);
+	STRING_PARAM(1, mode);
+	STRING_PARAM(2, encoding);
+	magic = (parms[5] == OBJ(PR_TRUE));
+	INT_32_PARAM(4, bufsize);
+	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
+
+	filep = self->data.ptr;
+	read_unlock(ist, self);
+	set_attr(ist, self, sym(ist, "encoding"), NEW_STRING(encoding));
+	if (magic) set_attr(ist, self, sym(ist, "magic"), OBJ(PR_TRUE));
+	else       del_attr(ist, self, sym(ist, "magic"));
+
+	if (strlen(mode) == 0) {
+		SET_TYPE_IF_EXC(TextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
+		set_file_obj_data(ist, self, parms[1], NULL, NULL, 0, 0);
+		read_lock(ist, self);
+		self->unclonable = TRUE;
+		return OBJ(NONE);
+	}
+	read_lock(ist, self);
+
+	if ((mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') ||
+	    (mode[1] != '+' && mode[1] != '\0')) {
+		raise_exception(ist, OBJ(TYPE_EXC), "TextFile mode `%s' is not valid", mode);
+		return NULL;
+	}
+
+	if (mode[0] == 'r') {
+		flags = APR_READ | APR_BINARY;
+		if (mode[1] == '+')
+			flags |= APR_WRITE;
+	} else if (mode[0] == 'w') {
+		flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY;
+		if (mode[1] == '+')
+			flags |= APR_READ;
+	} else if (mode[0] == 'a') {
+		flags = APR_WRITE | APR_CREATE | APR_APPEND | APR_BINARY;
+		if (mode[1] == '+')
+			flags |= APR_READ;
+	}
+
+	aprerr = apr_file_open(&f, path, flags, APR_OS_DEFAULT, filep->pool);
+	if (aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(IO_EXC), "Unable to open path %s: %s",
+				path, apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	read_unlock(ist, self);
+	SET_TYPE_IF_EXC(TextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
+	set_file_obj_data(ist, self, parms[1], parms[3], f, bufsize, flags);
+	read_lock(ist, self);
+	self->unclonable = TRUE;
+	return OBJ(NONE);
+}
+
 DEF(TextFile, str_, NULL) {
 	char buf[300], *path;
 	BIN_STR_CHK(TextFile);
@@ -1374,18 +1439,22 @@
 	return NEW_STRING(buf);
 }
 DEF(TextFile, read, FPARM1(size, NEW_INT(-1))) {
-	int readall = FALSE;
-	size_t size, total_read=0, num_read;
-	obj_p byt_obj;
-	byt_p obj_str;
+	int readall = FALSE, latin = FALSE;
+	data_size_t size, total_read=0, num_read;
+	obj_p str_obj;
 	u8_t* buf;
 	apr_status_t aprerr;
-	char err_buf[1024];
+	char *encoding, err_buf[1024];
 	i64_t size_in;
 
 	BIN_CONTENT_CHK(File);
 	INT_64_PARAM(1, size_in);
-
+	encoding = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "encoding")));
+	if (!strcmp(encoding, "latin-1")) latin = TRUE;
+	else if (strcmp(encoding, "ASCII")) {
+		raise_exception(ist, OBJ(VALUE_EXC), "encoding not supported: \"%s\"", encoding);
+		return NULL;
+	}
 	if (!has_proto(ist, self, File_OBJ)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "read can only be called on a File object");
 		return NULL;
@@ -1398,20 +1467,13 @@
 		raise_exception(ist, OBJ(IO_EXC), "read called on file opened without read perms");
 		return NULL;
 	}
-	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (!size_in) return NEW_STRING("");
 	if (size_in < 0) {
 		readall = TRUE;
 		size = BUFSIZE(self);
 	} else
-		size = (size_t) size_in;
-	byt_obj = NEW_OBJ(OBJ(BYTES_PROTO));
-	if (size < IMM_DATA_LEN) {
-		SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), byt_obj, DATA_TYPE_IMMDATA) return NULL;
-		buf = byt_obj->data.bytes;
-	} else {
-		obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
-		buf = obj_str->byt;
-	}
+		size = (data_size_t) size_in;
+	buf = pr_malloc(size);
 	num_read = size;
 	aprerr = apr_file_read(STREAM(self), buf, &num_read);
 	if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
@@ -1423,14 +1485,8 @@
 	while(aprerr != APR_EOF && (readall || total_read < size)) {
 		size_t next_read = (readall ? size : size - total_read);
 		size_t new_len   =  total_read + next_read;
-		if (byt_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMM_DATA_LEN) {
-			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
-			buf = obj_str->byt;
-		} else {
-			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
-			buf = obj_str->byt;
-		}
-		num_read = next_read;
+		buf = pr_realloc(buf, new_len);
+		num_read = (data_size_t) next_read;
 		aprerr = apr_file_read(STREAM(self), buf + total_read, &num_read);
 		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
 			raise_exception(ist, OBJ(IO_EXC), "%s",
@@ -1439,30 +1495,30 @@
 		}
 		total_read += num_read;
 	}
-	if (byt_obj->data_type == DATA_TYPE_IMMDATA)
-		byt_obj->imm_data_len = (int) total_read;
-	else {
-		obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+total_read+1);
-		obj_str->len = (data_size_t) total_read;
-		buf = obj_str->byt;
-	}
-	buf[total_read] = 0;
-	byt_obj->immutable = TRUE;
-	return byt_obj;
+	str_obj = NEW_OBJ(OBJ(STRING_PROTO));
+	c2pr_bytcpy(ist, str_obj, buf, total_read, latin);
+	pr_free(buf);
+	str_obj->immutable = TRUE;
+	return str_obj;
 }
 DEF(TextFile, readLine, FPARM1(size, NEW_INT(-1))) {
-	int readall = FALSE;
-	size_t size, total_read;
-	obj_p byt_obj;
-	byt_p obj_str;
+	int readall = FALSE, latin = FALSE;
+	data_size_t size, total_read;
+	obj_p str_obj;
 	u8_t* buf;
 	apr_status_t aprerr;
-	char err_buf[1024];
+	char *encoding, err_buf[1024];
 	i64_t  size_in;
 
 	BIN_CONTENT_CHK(File);
 	INT_64_PARAM(1, size_in);
 
+	encoding = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "encoding")));
+	if (!strcmp(encoding, "latin-1")) latin = TRUE;
+	else if (strcmp(encoding, "ASCII")) {
+		raise_exception(ist, OBJ(VALUE_EXC), "encoding not supported: \"%s\"", encoding);
+		return NULL;
+	}
 	if (!has_proto(ist, self, File_OBJ)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "readLine can only be called on a File object");
 		return NULL;
@@ -1475,70 +1531,57 @@
 		raise_exception(ist, OBJ(IO_EXC), "readLine called on file opened without read perms");
 		return NULL;
 	}
-	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (!size_in) return NEW_STRING("");
 	if (size_in < 0) {
 		readall = TRUE;
 		size = BUFSIZE(self);
 	} else
-		size = (size_t) size_in;
-	byt_obj = NEW_OBJ(OBJ(BYTES_PROTO));
-	if (size < IMM_DATA_LEN) {
-		SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), byt_obj, DATA_TYPE_IMMDATA) return NULL;
-		buf = byt_obj->data.bytes;
-	} else {
-		obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
-		buf = obj_str->byt;
-	}
+		size = (data_size_t) size_in;
+	buf = pr_malloc(size+1);
 	aprerr = apr_file_gets(buf, (int)(size + 1), STREAM(self));
 	if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
 		raise_exception(ist, OBJ(IO_EXC), "%s",
 				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
 		return NULL;
 	}
-	total_read = strlen(buf);
+	total_read = (data_size_t) strlen(buf);
 	while (aprerr != APR_EOF && buf[total_read-1] != '\n' && (readall || total_read < size)) {
 		size_t next_read = (readall ? size : size - total_read);
 		size_t new_len = total_read + next_read;
-		if (byt_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMM_DATA_LEN) {
-			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
-			buf = obj_str->byt;
-		} else {
-			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
-			buf = obj_str->byt;
-		}
+		buf = pr_realloc(buf, new_len+1);
 		aprerr = apr_file_gets(buf + total_read, (int)(next_read + 1), STREAM(self));
 		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
 			raise_exception(ist, OBJ(IO_EXC), "%s",
 					apr_strerror(aprerr, err_buf, sizeof(err_buf)));
 			return NULL;
 		}
-		total_read = strlen(buf);
+		total_read = (data_size_t) strlen(buf);
 	}
-	if (byt_obj->data_type == DATA_TYPE_IMMDATA)
-		byt_obj->imm_data_len = (int) total_read;
-	else {
-		obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+total_read+1);
-		buf = obj_str->byt;
-		obj_str->len = (data_size_t) total_read;
-	}
-	buf[total_read] = 0;
-	byt_obj->immutable = TRUE;
-	return byt_obj;
+	str_obj = NEW_OBJ(OBJ(STRING_PROTO));
+	c2pr_bytcpy(ist, str_obj, buf, total_read, latin);
+	pr_free(buf);
+	str_obj->immutable = TRUE;
+	return str_obj;
 }
 
 DEF(TextFile, readLines, FPARM1(size, NEW_INT(-1))) {
-	int readall = FALSE;
-	size_t size, total_read=0, num_read;
-	obj_p byt_obj, list_obj;
-	byt_p obj_str;
+	int readall = FALSE, latin = FALSE;
+	data_size_t size, total_read=0, num_read;
+	obj_p str_obj, list_obj;
 	u8_t* buf;
 	apr_status_t aprerr;
-	char err_buf[1024];
+	char *encoding, err_buf[1024];
 	i64_t  size_in;
 
 	BIN_CONTENT_CHK(File);
 	INT_64_PARAM(1, size_in);
 
+	encoding = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "encoding")));
+	if (!strcmp(encoding, "latin-1")) latin = TRUE;
+	else if (strcmp(encoding, "ASCII")) {
+		raise_exception(ist, OBJ(VALUE_EXC), "encoding not supported: \"%s\"", encoding);
+		return NULL;
+	}
 	if (!has_proto(ist, self, File_OBJ)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "readLines can only be called on a File object");
 		return NULL;
@@ -1551,23 +1594,16 @@
                 raise_exception(ist, OBJ(IO_EXC), "readLines called on file opened without read perms");
                 return NULL;
         }
-	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (!size_in) return NEW_STRING("");
 	if (size_in < 0) {
 		readall = TRUE;
 		size = BUFSIZE(self);
 	} else
-		size = (size_t) size_in;
+		size = (data_size_t) size_in;
 	list_obj = NEW_LIST(10);
 	aprerr = 0;
 	while (aprerr != APR_EOF && (readall || total_read < size)) {
-		byt_obj = NEW_OBJ(OBJ(BYTES_PROTO));
-		if (size < IMM_DATA_LEN) {
-			SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), byt_obj, DATA_TYPE_IMMDATA) return NULL;
-			buf = byt_obj->data.bytes;
-		} else {
-			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
-			buf = obj_str->byt;
-		}
+		buf = pr_malloc(size+1);
 		aprerr = apr_file_gets(buf, (int)(size - total_read + 1), STREAM(self));
 		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
 			raise_exception(ist, OBJ(IO_EXC), "%s",
@@ -1575,18 +1611,12 @@
 					err_buf, sizeof(err_buf)));
 			return NULL;
 		}
-		total_read += num_read = strlen(buf);
+		total_read += num_read = (data_size_t) strlen(buf);
 		while ( aprerr != APR_EOF && buf[num_read-1] != '\n' &&
 				                   (readall || total_read < size) ) {
 			size_t next_read = (readall ? size : size - total_read);
 			size_t new_len = num_read + next_read;
-			if (byt_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMM_DATA_LEN) {
-				obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
-				buf = obj_str->byt;
-			} else {
-				obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
-				buf = obj_str->byt;
-			}
+			buf = pr_realloc(buf, new_len+1);
 			aprerr = apr_file_gets(buf + num_read, (int)(next_read + 1), STREAM(self));
 			if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
 				raise_exception(ist, OBJ(IO_EXC), "%s",
@@ -1594,18 +1624,13 @@
 						err_buf, sizeof(err_buf)));
 				return NULL;
 			}
-			total_read += num_read = strlen(buf);
+			total_read += num_read = (data_size_t) strlen(buf);
 		}
-		if (byt_obj->data_type == DATA_TYPE_IMMDATA)
-			byt_obj->imm_data_len = (int) num_read;
-		else {
-			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+num_read+1);
-			buf = obj_str->byt;
-			obj_str->len = (data_size_t) num_read;
-		}
-		buf[num_read] = 0;
-		byt_obj->immutable = TRUE;
-		list_append(ist, list_obj, byt_obj);
+		str_obj = NEW_OBJ(OBJ(STRING_PROTO));
+		c2pr_bytcpy(ist, str_obj, buf, total_read, latin);
+		pr_free(buf);
+		str_obj->immutable = TRUE;
+		list_append(ist, list_obj, str_obj);
 	}
 	return list_obj;
 }
@@ -1613,13 +1638,19 @@
 DEF(TextFile, write, FPARM1(str, NULL)) {
 	apr_size_t size;
 	apr_status_t aprerr;
-	char err_buf[1024];
-	char* str;
+	char *encoding, err_buf[1024];
+	u8_t* buf;
+	int latin = FALSE;
 
 	BIN_CONTENT_CHK(File);
-	STRING_PARAM(1, str);
-	size = pr_strlen(parms[1]);
+	CHECK_TYPE_EXC(parms[1], OBJ(STRING_PROTO), String);
 
+	encoding = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "encoding")));
+	if (!strcmp(encoding, "latin-1")) latin = TRUE;
+	else if (strcmp(encoding, "ASCII")) {
+		raise_exception(ist, OBJ(VALUE_EXC), "encoding not supported: \"%s\"", encoding);
+		return NULL;
+	}
 	if (!has_proto(ist, self, File_OBJ)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "write can only be called from a File object");
 		return NULL;
@@ -1632,23 +1663,27 @@
 		raise_exception(ist, OBJ(IO_EXC), "write called on file opened without write perms");
 		return NULL;
 	}
+	buf = pr_malloc(size = pr_strlen(parms[1]));
+	pr_str2bytes(ist, buf, parms[1], latin);
 
-	aprerr = apr_file_write(STREAM(self), str, &size);
+	aprerr = apr_file_write_full(STREAM(self), buf, size, NULL);
 	if (aprerr != APR_SUCCESS) {
 		raise_exception(ist, OBJ(IO_EXC), "%s",
 				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
 		return NULL;
 	}
+	pr_free(buf);
 	return parms[1];
 }
 
 DEF(TextFile, writeLines, FPARM1(lst, NULL)) {
-	char* str;
 	apr_size_t size;
 	apr_status_t aprerr;
-	char err_buf[1024];
+	char *encoding, err_buf[1024];
+	u8_t* buf;
+	int latin = FALSE;
 
-	if (!has_proto(ist, parms[1], OBJ(SEQ_PROTO)) && !has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
+	if (!has_proto(ist, parms[1], OBJ(SEQ_PROTO)) && !has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "file writeLines parameter must be a sequence or a string");
 		return NULL;
 	}
@@ -1664,31 +1699,39 @@
 		raise_exception(ist, OBJ(IO_EXC), "writeLines called on file opened without write perms");
 		return NULL;
 	}
+	encoding = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "encoding")));
+	if (!strcmp(encoding, "latin-1")) latin = TRUE;
+	else if (strcmp(encoding, "ASCII")) {
+		raise_exception(ist, OBJ(VALUE_EXC), "encoding not supported: \"%s\"", encoding);
+		return NULL;
+	}
 	if (has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
-		str  = pr2c_strptr(ist, parms[1]);
-		size = pr_strlen(parms[1]);
-		aprerr = apr_file_write(STREAM(self), str, &size);
+		buf = pr_malloc(size = pr_strlen(parms[1]));
+		pr_str2bytes(ist, buf, parms[1], latin);
+		aprerr = apr_file_write_full(STREAM(self), buf, size, NULL);
 		if (aprerr != APR_SUCCESS) {
 			raise_exception(ist, OBJ(IO_EXC), "%s",
 					apr_strerror(aprerr, err_buf, sizeof(err_buf)));
 			return NULL;
 		}
+		pr_free(buf);
 	} else {
 		int i, llen = (int) list_len(ist, parms[1]);
 		for(i = 0; i < llen; i++) {
 			obj_p item = list_item(ist, parms[1], i);
 			if (!has_proto(ist, item, OBJ(STRING_PROTO))) {
-				raise_exception(ist, OBJ(TYPE_EXC), "writeLines first item must be a string");
+				raise_exception(ist, OBJ(TYPE_EXC), "writeLines list items must be strings");
 				return NULL;
 			}
-			str  = pr2c_strptr(ist, item);
-			size = pr_strlen(item);
-			aprerr = apr_file_write(STREAM(self), str, &size);
+			buf = pr_malloc(size = pr_strlen(parms[1]));
+			pr_str2bytes(ist, buf, parms[1], latin);
+			aprerr = apr_file_write_full(STREAM(self), buf, size, NULL);
 			if (aprerr != APR_SUCCESS) {
 				raise_exception(ist, OBJ(IO_EXC), "%s",
 						apr_strerror(aprerr, err_buf, sizeof(err_buf)));
 				return NULL;
 			}
+			pr_free(buf);
 		}
 	}
 	return parms[1];
@@ -1761,6 +1804,7 @@
 
 	MODULE_SUB_INIT(TextFile);
 	MODULE_ADD_SYM(TextFile, init_);
+	MODULE_ADD_SYM(TextFile, open);
 	MODULE_ADD_SYM(TextFile, str_);
 	MODULE_ADD_SYM(TextFile, read);
 	MODULE_ADD_SYM(TextFile, readLine);
Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-19 01:41:25 UTC (rev 638)
+++ trunk/src/object.h	2004-06-19 03:10:09 UTC (rev 639)
@@ -153,6 +153,7 @@
 size_t bytes_len(obj_p obj);
 void pr_str2bytes(isp ist, u8_t* buf, obj_p str_obj, int latin);
 void pr2pr_strcpy(isp ist, obj_p obj, ch3_p str, data_size_t len);
+void c2pr_bytcpy(isp ist, obj_p obj, u8_t* byt, data_size_t len, int latin);
 
 void dict2attrs(isp ist, obj_p dict, obj_p obj);
 void list2protos(isp ist, obj_p list, obj_p obj);