Wednesday, November 23, 2011

memcpy and memmove

It is interesting to notice the difference between the memcpy and memmove when programming in C. 

While the memcpy copies the data byte-by-byte sequentially from source to destination, the memmove function copies the block of data to the source to the destination. The difference implies that the memcpy function can generate the repeating data results (see below) if the source data being copied happens to be overlapping with the destination data:

#include <stdio.h>
#include <string.h>


int main()
{
    char src1[] = "abcdefg";
    char src2[] = "abcdefg";
    char *dest1;
    char *dest2;
    
    if ((dest1 = (char*)malloc(8*sizeof(char))) == NULL
        || (dest2 = (char*)malloc(8*sizeof(char))) == NULL)
        exit(1);
    
    //memcpy src1 -> dest1
    memcpy(dest1, src1, 7);
    printf("memcpy\tsrc1:%s\tdest1:%s\n", src1, dest1);
    
    //memmove src2 -> dest2
    memmove(dest2, src2, 7);
    printf("memmove\tsrc2:%s\tdest2:%s\n", src2, dest2);
    
    //memcpy src1 -> src1+1
    memcpy(src1+1, src1, 6);
    printf("memcpy\tsrc1:%s\n", src1);
        
    //memmove src2 -> src2+1
    memmove(src2+1, src2, 6);
    printf("memmove\tsrc2:%s\n", src2);
    
    free (dest1);
    free (dest2);
    return 0;
}

The result would be:


memcpy  src1:abcdefg    dest1:abcdefg
memmove src2:abcdefg    dest2:abcdefg
memcpy  src1:aaaaaaa
memmove src2:aabcdef


Thus, memcpy should be used with caution when the data is overlapping with each other.  Specifically, the memmove works identically to memcpy if:
src_addr + length_copy < dest_addr or src_addr > dest_addr 
and it works reversely in the other way. So, the memmove can also be implemented as memmove2:


void * memmove2(void *dest, const void *src, size_t len)
{
    if (src != dest)
    {
        if ((const char*)src+len < dest || (const char*)src > dest)
            memcpy(dest, src, len);
        else
            while (len--)
                *((char*)dest+len) = *((const char*)src+len);
    }
    return dest;
}

If we compare the following code snippets, the running time are also different between:

    for (i = 0; i < 100000000; i++)
        memmove(dest, src, n);

and

    for (i = 0; i < 100000000; i++)
        memmove2(dest, src, n);


The results depend on the relationship between dest and src, where n denotes the length of string to be copied:

                dest < src | dest==src | dest > src | dest > src + n
    memmove         4.020       0.321       18.070      4.036
   memmove2         3.148       0.892       3.096       3.295

The running time is in second. It is obvious that while the memmove2 function outperforms the standard function in cases where dest!=src, the memmove is better when dest==src.


(Compiled using gcc 3.4.4)

Sunday, November 13, 2011

Use Mock GPS Location for Android Development - Part Two

In the first part of this topic, several simple methods for sending mock GPS location data to the device or emulator have been discussed. They are convenient when you need only test one GPS location at a time. However, when you want to test a consecutive points set (e.g. a route for a moving vehicle) for your app, these methods are not that handy. Therefore, in this part, two other simple ways for mock continuous GPS locations for testing your app are provided: one is using KML file, another way is writing a small app to provide the mock GPS locations updates.

Using KML on DDMS:

The easiest way to send a path of GPS points to the emulator is through the Location Controls in the DDMS for Android emulator. Just need a KML file for storing the path, and use DDMS to send this path of locations to the emulator at a certain interval.

1. Start the Google Earth desktop application and click on "Add" and then "Path" to draw the path:


2. "Cltr+S" to export the route as a kml file on to your disk;

3. Use a web tool (e.g.ge2adt) to convert that the Goolge Earth route into the Eclipse ADT compatible kml format; (here is the sample kml route file after the conversion)

Or, if you don't want to use Google Earth, the KML file format for the Android emulator is like:



4. Start the Android emulator and your GPS location app; Click on the "Load KML..." on the Location Controls field in the DDMS to load the path kml:

Using the MockLocationBuilder:

The following small app is to send the mock locations that a user has specified to the emulator (or real device). The app works like this:

1. Start the MockLocationBuilder and draw the path;
2. Start the test GPS;
3. Start the target app that use the test GPS's updates (e.g. Google Map on Android).



You can download the code from here.

The app supports:
1. Define the path
2. Generate the mock GPS updates loop around the path at regular interval
3. Work in the background (allow you to start the target app)

About the Code:

The MockLocationBuilder class extends the MapActivity class to display and manage the map:

public class MockLoctionBuilderActivity extends MapActivity
Then specify the location provider's name:

static private String mTestProvider = LocationManager.GPS_PROVIDER;
To add the mock location provider, you can use this function:

 private void addMockLocationManager() {
  mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  if (mLocManager.getProvider(mTestProvider) == null)
  {
   mLocManager.addTestProvider(mTestProvider, false, false,
    false, false, false, false, false,
    android.location.Criteria.POWER_HIGH,
    android.location.Criteria.ACCURACY_FINE);
  }
  mLocManager.setTestProviderEnabled(mTestProvider, true);
 }


Note that you can only specify the provider to be LocationManager.GPS_PROVIDER on the emulator but not on a real device, because the addTestProvider method will throw the error for the provider named "gps". To use on the device, you can specify the mTestProvider as some other strings.

And set the mock location at a regular interval through this method:

 private void setMockLocation(double latitude, double longitude) {
  Location newLocation = new Location(mTestProvider);
  newLocation.setLatitude(latitude);
  newLocation.setLongitude(longitude);
  newLocation.setTime(System.currentTimeMillis());
  mLocManager.setTestProviderLocation(mTestProvider,
    newLocation);
 }

Note that the newLocation.setTime method set the timestamp when the new location is generated, which makes the location listener takes in it as an updated location.

Release the provider after the running by:

if (mLocManager.getProvider(mTestProvider) != null)
    mLocManager.removeTestProvider(mTestProvider);
 


PS: 1. On the device, remember that the system might setup the LocationManager.GPS_PROVIDER as the default provider, so that you cannot call the addTestProvider method on it. However, you can specify the test provider to be some other name and use the same test provider in the target app for location updates;

2. You may want to change the frequency of the GPS updates.


Ref:
This post provides more detailed discription of the important methods:
http://ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/

Thursday, October 13, 2011

malloc() and free()

In C, the malloc() and free() function allows dynamic memory management. However, when using this function with char string (char*), sometimes it is easy to forget padding '\0' after the string:
int main() {
    size_t i;
    char *str1;
    for (i = 0; i < 3; i++)
    {
        str1 = (char*)malloc(10 * sizeof(char));
        memset (str1, 'a', 9-i);
        printf("ADDRESS:0x%x  DATA:%s\n", str1, str1);
        free(str1);
    }
    return 0;
}
And the output might be something like:

ADDRESS:0x4701e0  DATA:aaaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaaa►
ADDRESS:0x4701e0  DATA:aaaaaaaa►

The reason for that whenever free(pointer) is called in the C program, the space pointed by the pointer is collected back in the free mem list which can be reused later by another malloc call. So depending on the mechanism of free(), there is a chance that the content in the part of the memory to which a pointer previously points, was not erased after calling free() (ref here). Then we can see the previous content in the pointer, if no '\0' was padding to the end of str1.


Normally, I choose to add memset after malloc, or pad a '\0' to the end, or use calloc instead, e.g. in the loop:



        str1 = (char*)malloc(10 * sizeof(char));
       
// Option 1. Add memset to set the init values
        //memset (str1, '\0', 10);

        // Option 2. Use calloc() to init to NULL instead
        //str1 = (char*)calloc(10, sizeof(char));

        memset (str1, 'a', 9-i);
        // Option 3. Add the '\0' to the end
        //*(str1+9-i) = '\0';

        printf("ADDRESS:0x%x  DATA:%s\n", str1, str1);
        free(str1);

Then the result will be good:

ADDRESS:0x4701e0  DATA:aaaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaa
















Tuesday, October 4, 2011

How to use strptime() function in Windows

The GNU C strptime function is used to convert a given string (s), which is described as format, into a standard C time struct called tm:

char *strptime(const char *s, const char *format, struct tm *tm);


This time function is very handy when you try to convert a DateTime string into a time struct in C. And is often used together with its counterpart, strftime, to perform translation of the input DateTime string in the original format into the target format (e.g. here).


Recently, when working with the program using VS 2005 compiler, I found that the strptime function was not supported in the Windows' compiler. When checking out the time.h header file in \VC\include\time.h in the Visual Studio folders, you won't see the declaration of the strptime. So in order to use this function on Windows:


1. Since the glibc is designed for UNIX-like system, and it is advisable to use a gcc compiler on Windows (e.g. cygwin) to compile your program;


2. Or use other implementations instead:
1) http://plibc.sourceforge.net/doxygen/strptime_8c-source.html
2) http://www.opensource.apple.com/source/lukemftp/lukemftp-3/lukemftp/libukem/strptime.c
3) (In C++, Boost C++ Libs) http://www.boost.org/doc/libs/1_47_0/doc/html/date_time/date_time_io.html


3. Or write your own conversion function strptime().



Wednesday, September 21, 2011

Use Mock GPS Location for Android Development - Part One

Recently, I am working on an Android google map app that requires some fake GPS position input. Here are several easy ways for you to quickly input mock GPS locations for your Android development:

Using Emulator:
1. Using geo fix 
cd to your .\android-sdk\tools\ folder, and then telnet to your avd. e.g.
$ telnet localhost 5554
$ geo fix -118 35
$ exit
The help geo fix shows that it takes these parameters 'geo fix log lat '...

2. Using DDMS
In your emulator control view, using the Location Controls to send the location, e.g.

Using Android Device:

Use mock location generation tool like Location Spooler: https://market.android.com/details?id=org.ajeje.fakelocation&feature=related_apps

1) Start location spooling


2) Start the app


Note:
1. Remember to save in the android manifest xml the mock location permission;
2. Enable the mock GPS location access on your droid phone. 

Also refer to here:
http://stackoverflow.com/questions/2531317/android-mock-location-on-device


Wednesday, September 14, 2011

A very simple gcc makfile for Creating and Linking a static C lib on Windows

The short makfile script below is to create and use a static c lib in gcc compiler for C code.


Requirement:
1. gcc compiler (e.g. cygwin);
2. Put in a folder the following files:
   main.c //main program, to call mylib.lib
   mylib.c //lib's src, to generate mylib.lib
   mylib.h //lib's hearder
   makefile


makefile:
#my library
LIB_SRC = mylib.c
LIB_DEP = $(LIB_SRC:.c=.h)
LIB_OBJ = $(LIB_SRC:.c=.o)
LIB = $(LIB_SRC:.c=.lib)
#main program
SRC = main.c
BIN = main.exe
# include directories
INCLUDES = -I.
# compiler
CC = gcc
# dependency
$(BIN): $(LIB) $(SRC)
$(CC) -o $(BIN) $(SRC) $(LIB)
$(LIB): $(LIB_OBJ)
ar rcs $(LIB) $(LIB_OBJ)
$(LIB_OBJ): $(LIB_SRC) $(LIB_DEP)
$(CC) -c -o $@ $< $(INCLUDES)
clean:
rm -f $(LIB_OBJ) $(LIB) $(BIN)


Add tab before for each command line.


Usage:
To run on a UNIX-like command line tool in Windows:
$ make
or
$ make main.exe
will compile and generate both mylib.lib and main.exe
$ make mylib.lib
will compile and generate only mylib.lib


For more info: GNU `make`

Thursday, April 14, 2011

Calculate Elapsed Time in C


We can use the function and structs in standard C library (sys/time.h) to calculate the elapsed time value between two time instances:

1. To get the processor time of the program, we use the C library clock_t struct to count the CPU clock ticks, and then divide the CLOCKS_PER_SEC to get the time:

    e.g.
        clock_t t;
        t = clock();   
        // Do something
        t = clock() - t;
        double cpu_time_elapsed = (double)t/CLOCKS_PER_SEC;


2. To calculate the time interval in wall clock time, use the C library time_t struct and the time difference function:
   
    double difftime(time_t end, time_t start)
   
  , where the start and end time can be initialized by calling time_t time(time_t *time) function, and the return value is the seconds (in double) elapsed between start and end.

    e.g.   
        time_t start, end;
        time(&start);
        // Do something
        time(&end);
        double time_elapsed = difftime(end, start);


3. To calculate the time interval more precisely (in higher resolution), we can define a C function like:

    double getTimeElapsed(struct timeval end, struct timeval start)
    {
        return (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.00;
    }

  , where the struct timeval is elapsed time declared in the sys/time.h. It contains two members:

        tv_sec (number of seconds elapsed)
       
  and
 
        tv_usec (remaining second fraction in microseconds).

    To get the start and end time value, we call the gettimeofday() function.
 
    e.g.
        timeval start, end;
        gettimeofday(&start, NULL);
        // Do something
        gettimeofday(&end, NULL);
        double time_elapsed = getTimeElapsed(end, start);

       
    Another time struct, timespec has two members tv_sec and tv_nsec, where tv_nsec represent remaining second fraction in nanosecond.
   

Reference: 
1. GNU C Library Manual: 21.2 Elapsed Time
2. difftime on cplusplus.com

Sunday, April 3, 2011

Install Ubuntu 10.10 using wubi on Windows 7 (Avoid Permission Denied Error)

Problem:

Wubi provides a fast and convinient way for us to install Ubuntu on an existing Windows OS. However, when I was installing Ubuntu 10.10 by wubi on Windows 7, I got an error message "An error occured: Permission Denied".

Solution:

To solve this problem, you can do the following:
  1. Download the CD image xxx.iso (e.g. Intel x86 Desktop: ubuntu-10.10-desktop-i386.iso) and save to under your partition (e.g. D:/).
  2. Unmount the image file with either DAEMON tool, WinRAR or 7zip, extract the wubi.exe file to the folder containing the image file.
  3. Run the wubi.exe (and no "permission denied" error will occur!)
  4. You can choose to delete the image file after reboot.
Done and enjoy!

Saturday, April 2, 2011

1. Yii - Framework Installation

# 0. preparation
- LAMP

# 1. create a project from yii:
- cd to the web root and run the follow in the cmd:
 
# 2. config the project
- go to the ./config/main.php
- remove the comment and add your customed password of the generator
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'[YOURPASSWORD]',
'ipFilters'=>array('127.0.0.1','::1'),
),
 
- also have an application base directory /wwwroot/project_name/protected. It should be protected from being accessed by Web users. For Apache httpd Web server, we place under this directory a .htaccess file with the following content:
 
- set up create and write access to the view, model and controller folder
chmod -777 view -R
chmod -777 controller -R
chmod -777 model -R

- The gii tool should be removed when running on the production machine.
- The debug mode should also be disabled on a production machine.

# 3. then edit the view/greeting page
- localhost/[project]/index.php?r=greeting/index
r = route the request takes the controller id / action id pair
greeting = controller id - tells greeting controller class
index = action id - tells to use the action index in the class
- $this in the view file refers to the controller class which renders it

# 4. config database
- Config the database in the config/main.php and uncomment the mysql
- change the database name, password, username for the mysql
- go to gii "Model Class" to create the model of [modelid]
- name the table prefix, name class.
the table prefix fields will ignore the prefix will choosing the model class

# 5. create the ORM using CRUD module
- go to the crud module and type in the [modelid]
- create the crud object
- go to the link: index.php?r=[modelid]


Reference:
1. http://www.yiiframework.com/doc/guide/1.1/en/quickstart.installation
2. http://www.yiiframework.com/screencasts/


deny from all

yii/framework/yiic webapp [project_name]