[Tcladdressbook-commits] Source TclAddressBook.c,1.9,1.10
Status: Alpha
Brought to you by:
bdesgraupes
|
From: <bde...@us...> - 2003-12-06 15:37:19
|
Update of /cvsroot/tcladdressbook/Source
In directory sc8-pr-cvs1:/tmp/cvs-serv23281/Source
Modified Files:
TclAddressBook.c
Log Message:
New [import], [export] and [image] commands
Index: TclAddressBook.c
===================================================================
RCS file: /cvsroot/tcladdressbook/Source/TclAddressBook.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- TclAddressBook.c 6 Dec 2003 06:19:43 -0000 1.9
+++ TclAddressBook.c 6 Dec 2003 15:37:16 -0000 1.10
@@ -1,7 +1,7 @@
/*
* File : "TclAddressBook.c"
* Created: 2003-11-26 12:54:15
- * Last modification: 2003-12-06 06:36:29
+ * Last modification: 2003-12-06 16:29:57
* Author: Bernard Desgraupes
* e-mail: <bde...@ea...>
*
@@ -30,7 +30,10 @@
static int TclABCmd_Changed(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_Count(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_GetMe(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
+static int TclABCmd_Export(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_Groups(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
+static int TclABCmd_Image(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
+static int TclABCmd_Import(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_Parents(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_Persons(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
static int TclABCmd_Properties(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tcl_Obj *resultPtr);
@@ -118,15 +121,15 @@
int index, result;
static CONST char *switches[] = {
- "add", "changed", "count", "getme", "groups",
- "parents", "persons", "properties", "record", "remove",
- "save", "search", "type", "value", (char *) NULL
+ "add", "changed", "count", "export", "getme", "groups",
+ "image", "import", "parents", "persons", "properties",
+ "record", "remove", "save", "search", "type", "value", (char *) NULL
};
enum {
- TCLAB_ADD, TCLAB_CHANGED, TCLAB_COUNT, TCLAB_GETME, TCLAB_GROUPS,
- TCLAB_PARENTS, TCLAB_PERSONS, TCLAB_PROPERTIES, TCLAB_RECORD, TCLAB_REMOVE,
- TCLAB_SAVE, TCLAB_SEARCH, TCLAB_TYPE, TCLAB_VALUE
+ TCLAB_ADD, TCLAB_CHANGED, TCLAB_COUNT, TCLAB_EXPORT, TCLAB_GETME, TCLAB_GROUPS,
+ TCLAB_IMAGE, TCLAB_IMPORT, TCLAB_PARENTS, TCLAB_PERSONS, TCLAB_PROPERTIES,
+ TCLAB_RECORD, TCLAB_REMOVE, TCLAB_SAVE, TCLAB_SEARCH, TCLAB_TYPE, TCLAB_VALUE
};
resultPtr = Tcl_GetObjResult(interp);
@@ -154,6 +157,10 @@
result = TclABCmd_Count(clientData, interp, objc, objv, resultPtr);
break;
+ case TCLAB_EXPORT:
+ result = TclABCmd_Export(clientData, interp, objc, objv, resultPtr);
+ break;
+
case TCLAB_GETME:
result = TclABCmd_GetMe(clientData, interp, objc, objv, resultPtr);
break;
@@ -162,6 +169,14 @@
result = TclABCmd_Groups(clientData, interp, objc, objv, resultPtr);
break;
+ case TCLAB_IMAGE:
+ result = TclABCmd_Image(clientData, interp, objc, objv, resultPtr);
+ break;
+
+ case TCLAB_IMPORT:
+ result = TclABCmd_Import(clientData, interp, objc, objv, resultPtr);
+ break;
+
case TCLAB_PARENTS:
result = TclABCmd_Parents(clientData, interp, objc, objv, resultPtr);
break;
@@ -400,6 +415,82 @@
/*
*----------------------------------------------------------------------
*
+ * TclABCmd_Export --
+ *
+ * This procedure is invoked to process the [addressbook export] Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Syntax:
+ * addressbook export personID
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclABCmd_Export(
+ ClientData /* clientData */, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument values. */
+ Tcl_Obj *resultPtr) /* Pointer to store the result. */
+{
+ ABAddressBookRef ab;
+ ABRecordRef theRecord;
+ CFStringRef uidRef;
+ CFDataRef vCard;
+ int length, kind;
+ Tcl_Obj * objPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "personID");
+ return TCL_ERROR;
+ }
+
+ uidRef = CFStringCreateWithCString(NULL, Tcl_GetStringFromObj(objv[2], &length), GetApplicationTextEncoding());
+ // Get the address book
+ ab = ABGetSharedAddressBook();
+ // Find the record corresponding to the UID
+ theRecord = ABCopyRecordForUniqueId(ab, uidRef);
+ CFRelease(uidRef);
+ if (!theRecord) {
+ Tcl_AppendStringsToObj(resultPtr, "Unrecognized record ID", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ // Is it a person or a group?
+ kind = TclAB_TypeFromRecord(ab, theRecord);
+ if (kind != rec_person) {
+ Tcl_AppendStringsToObj(resultPtr, "Not a person record", (char *) NULL);
+ CFRelease(theRecord);
+ return TCL_ERROR;
+ }
+
+ vCard = ABPersonCopyVCardRepresentation(theRecord);
+ if (vCard) {
+ objPtr = Tcl_NewByteArrayObj( CFDataGetBytePtr(vCard), CFDataGetLength(vCard) );
+ Tcl_SetObjResult(interp, objPtr);
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't get vCard representation", (char *) NULL);
+ CFRelease(theRecord);
+ return TCL_ERROR;
+ }
+
+ CFRelease(vCard);
+ CFRelease(theRecord);
+ return TCL_OK;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclABCmd_GetMe --
*
* This procedure is invoked to process the [addressbook getme] Tcl command.
@@ -482,6 +573,213 @@
/*
*----------------------------------------------------------------------
*
+ * TclABCmd_Image --
+ *
+ * This procedure is invoked to process the [addressbook image] Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Syntax:
+ * addressbook image personID ?imageData?
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclABCmd_Image(
+ ClientData /* clientData */, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument values. */
+ Tcl_Obj *resultPtr) /* Pointer to store the result. */
+{
+ ABAddressBookRef ab;
+ ABRecordRef theRecord;
+ CFStringRef uidRef;
+ CFDataRef imageRef;
+ int length, kind, result;
+ Tcl_Obj * objPtr;
+ Boolean setIt = false;
+ unsigned char * imageBytes;
+
+ Tcl_ResetResult(interp);
+ result = TCL_OK;
+
+ if (objc != 3 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "personID");
+ return TCL_ERROR;
+ }
+
+ if (objc == 4) {
+ imageBytes = Tcl_GetByteArrayFromObj(objv[3], &length);
+ setIt = true;
+ }
+
+ uidRef = CFStringCreateWithCString(NULL, Tcl_GetStringFromObj(objv[2], &length), GetApplicationTextEncoding());
+ // Get the address book
+ ab = ABGetSharedAddressBook();
+ // Find the record corresponding to the UID
+ theRecord = ABCopyRecordForUniqueId(ab, uidRef);
+ CFRelease(uidRef);
+ if (!theRecord) {
+ Tcl_AppendStringsToObj(resultPtr, "Unrecognized record ID", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ // Is it a person or a group?
+ kind = TclAB_TypeFromRecord(ab, theRecord);
+ if (kind != rec_person) {
+ Tcl_AppendStringsToObj(resultPtr, "Not a person record", (char *) NULL);
+ CFRelease(theRecord);
+ return TCL_ERROR;
+ }
+
+ if (setIt) {
+ imageRef = CFDataCreate(NULL, imageBytes, length);
+ if (!imageRef) {
+ Tcl_AppendStringsToObj(resultPtr, "CFDataCreate error", (char *) NULL);
+ result = TCL_ERROR;
+ } else {
+ if (!ABPersonSetImageData(theRecord, imageRef)) {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't set image data", (char *) NULL);
+ result = TCL_ERROR;
+ }
+ }
+ } else {
+ imageRef = ABPersonCopyImageData(theRecord);
+ if (!imageRef) {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't get image data", (char *) NULL);
+ result = TCL_ERROR;
+ } else {
+ objPtr = Tcl_NewByteArrayObj( CFDataGetBytePtr(imageRef), CFDataGetLength(imageRef) );
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ }
+
+ if (imageRef) CFRelease(imageRef);
+ CFRelease(theRecord);
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclABCmd_Import --
+ *
+ * This procedure is invoked to process the [addressbook import] Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Syntax:
+ * addressbook import vCardData
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclABCmd_Import(
+ ClientData /* clientData */, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument values. */
+ Tcl_Obj *resultPtr) /* Pointer to store the result. */
+{
+
+ ABAddressBookRef ab;
+ ABPersonRef importedRecord, newRecord;
+ CFStringRef theValue, theProperty, uidRef;
+ CFArrayRef allProps;
+ CFDataRef vCard;
+ CFIndex theCount;
+ char theUID[256];
+ int i, length, result;
+ Tcl_Obj * objPtr;
+ unsigned char * theBytes;
+
+ Tcl_ResetResult(interp);
+ result = TCL_OK;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "VCardData");
+ return TCL_ERROR;
+ }
+
+ theBytes = Tcl_GetByteArrayFromObj(objv[2], &length);
+
+ vCard = CFDataCreate(NULL, theBytes, length);
+ if (!vCard) {
+ Tcl_AppendStringsToObj(resultPtr, "CFDataCreate error", (char *) NULL);
+ result = TCL_ERROR;
+ } else {
+ // Import the VCard
+ importedRecord = ABPersonCreateWithVCardRepresentation(vCard);
+ CFRelease(vCard);
+ // Adding the imported record directly to the database causes a
+ // crash. So we create a new record and copy the improted property/value
+ // pairs to the new record.
+ newRecord = ABPersonCreate();
+ if (!importedRecord || !newRecord) {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't create new record with VCard data", (char *) NULL);
+ result = TCL_ERROR;
+ } else {
+ // Get the address book
+ ab = ABGetSharedAddressBook();
+ // Loop over all the properties and copy them the the new record
+ allProps = ABCopyArrayOfPropertiesForRecordType(ab, kABPersonRecordType);
+ theCount = CFArrayGetCount(allProps);
+ for (i = 0; i < theCount; i++) {
+ // Get the property at index i
+ theProperty = CFArrayGetValueAtIndex(allProps, i);
+ if (theProperty) {
+ theValue = ABRecordCopyValue(importedRecord, theProperty);
+ if (!theValue) {
+ continue;
+ }
+ ABRecordSetValue(newRecord, theProperty, theValue);
+ CFRelease(theValue);
+ }
+ }
+ if (allProps) CFRelease(allProps);
+
+ // TODO: also copy the image if any
+
+ // Add the new record to the Address Book. Don't save here: leave
+ // this to the Tcl level.
+ if ( ABAddRecord(ab, newRecord) ) {
+ // Retrieve the UID for the newly created record
+ uidRef = ABRecordCopyUniqueId(newRecord);
+ if (uidRef) {
+ CFStringGetCString(uidRef, theUID, sizeof(theUID), GetApplicationTextEncoding());
+ CFRelease(uidRef);
+ Tcl_AppendStringsToObj(resultPtr, theUID, (char *) NULL);
+ }
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't add record to the Address Book", (char *) NULL);
+ result = TCL_ERROR;
+ }
+ }
+ if (importedRecord) CFRelease(importedRecord);
+ if (newRecord) CFRelease(newRecord);
+ }
+
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclABCmd_Parents --
*
* This procedure is invoked to process the [addressbook parents] Tcl command.
@@ -510,10 +808,9 @@
CFArrayRef allParents;
ABRecordRef theRecord;
CONST84 char * groupUID;
- CFStringRef uidCFStr;
+ CFStringRef uidRef;
int index, kind, length;
ABAddressBookRef ab;
- TextEncoding theEncoding = GetApplicationTextEncoding();
Boolean onlyID = false;
static CONST char *parentsSwitches[] = {
@@ -541,11 +838,11 @@
ab = ABGetSharedAddressBook();
groupUID = Tcl_GetStringFromObj(objv[2], &length);
- uidCFStr = CFStringCreateWithCString(NULL, groupUID, theEncoding);
+ uidRef = CFStringCreateWithCString(NULL, groupUID, GetApplicationTextEncoding());
// Find the record corresponding to the UID
- theRecord = ABCopyRecordForUniqueId(ab, uidCFStr);
- CFRelease(uidCFStr);
+ theRecord = ABCopyRecordForUniqueId(ab, uidRef);
+ CFRelease(uidRef);
if (!theRecord) {
Tcl_AppendStringsToObj(resultPtr, "Unrecognized record ID", (char *) NULL);
return TCL_ERROR;
@@ -731,9 +1028,8 @@
ABRecordRef theRecord;
CONST84 char * var;
CONST84 char * theUID;
- CFStringRef uidCFStr;
+ CFStringRef uidRef;
int length, kind;
- TextEncoding theEncoding = GetApplicationTextEncoding();
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "recordID arrayvar");
@@ -743,12 +1039,12 @@
var = Tcl_GetStringFromObj(objv[3], &length);
theUID = Tcl_GetStringFromObj(objv[2], &length);
- uidCFStr = CFStringCreateWithCString(NULL, theUID, theEncoding);
+ uidRef = CFStringCreateWithCString(NULL, theUID, GetApplicationTextEncoding());
// Get the address book
ab = ABGetSharedAddressBook();
// Find the record corresponding to the UID
- theRecord = ABCopyRecordForUniqueId(ab, uidCFStr);
- CFRelease(uidCFStr);
+ theRecord = ABCopyRecordForUniqueId(ab, uidRef);
+ CFRelease(uidRef);
if (!theRecord) {
Tcl_AppendStringsToObj(resultPtr, "Unrecognized record ID", (char *) NULL);
return TCL_ERROR;
@@ -758,6 +1054,7 @@
kind = TclAB_TypeFromRecord(ab, theRecord);
if (kind == rec_undefined) {
Tcl_AppendStringsToObj(resultPtr, "Unknown type for recordID argument", (char *) NULL);
+ CFRelease(theRecord);
return TCL_ERROR;
}
|