Thursday, July 29, 2010

Summary on web app layers and languages

Web Languages: Decoded (Chinese version)

This article is a summary on web application layers and languages. Not totally accurate in some places. But is a good summary anyways.

Tuesday, July 27, 2010

Drupal Customization - Add New tab to a page

In a Drupal content page, when the user is logged in, on the top of the page there are "View" and "Edit" link buttons for the user to view and edit the content of the page. Now we want to add a "New" link button to allow the user create a new page of this type. This can be done this way.

In "themes -> [theme folder] -> page.tpl.php", we have these two lines:

<?php if ($title): print '<h2'. ($tabs ? ' class="with-tabs"' : '') .'>'. $title .'</h2>'; endif; ?>
<?php if ($tabs): print '<ul class="tabs primary">'. $tabs . '</ul></div>'; endif; ?>

The first line is for the title. The second line is for the tabs "View" and "Edit". So we change the second line to be:

<?php if ($tabs): print '<ul class="tabs primary">'. $tabs . print_custom_tab($node) . '</ul></div>'; endif; ?>

And define the print_custom_tab() function at the end of the page:
<?php
function print_custom_tab($node) {
// Use this to limit the "New" tab to certain page types.
//if (substr($node->type, 0) == "[page type name]")
{
return "<li><a href='?q=node/add/" . str_replace("_", "-", $node->type) . "'>New</a></li>";
}
}
?>

From the $node we can also get $node->uid and other variables associated with node, and can do many other things this way.

Alternatively or in a cleaner way, there is an Add another module that do this. It needs to be configured on what page type and when to show. The configuration is done in "Administer -> Site configuration -> Add another".

Monday, July 26, 2010

C# read Excel, get Access schema

///
/// Reference: How To Open and Read an Excel Spreadsheet into a ListView in .NET
///
public static void readExcel(string fullpath) {
Excel.Application excelObj = new Excel.Application();
if (excelObj == null) {
MessageBox.Show("Error: Excel cannot be started.");
return;
}

excelObj.Visible = false;

Excel.Workbook theWorkbook = excelObj.Workbooks.Open(fullpath, 0, true, 5, "", "",
true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, false, false, false);
// get the collection of sheets in the workbook
Excel.Sheets sheets = theWorkbook.Worksheets;
// get the first and only worksheet from the collection of worksheets
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);

// getExcelSize(worksheet); // get row/col: ws.Rows.Count, ws.Columns.Count

// loop through 10 rows of the spreadsheet and place each row in the list view
for (int i = 1; i <= 10; i++)
{
Excel.Range range = worksheet.get_Range("A"+i.ToString(), "FB" + i.ToString());
System.Array myvalues = (System.Array)range.Cells.Value2;
string str = ConvertArrayToString(myvalues);
MessageBox.Show(str);
}
}


///
/// Reference: How to read an Excel file with OleDb and a simple SQL query?
/// To use this, the Excel version should be 8.0 or compatible.
///
/// The link http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=107963&SiteID=1
/// says that to use this method, it takes a little setup in your Excel document.
/// Basically, you need to define "named objects" in Excel that are synonymous to
/// tables in a database. The first row of the named object are the column headers.
/// To set up a named object, first select the range of cells (your "table," with
/// the first row being the column headers), then go to menu Insert->Names->Define.
/// Name your object and press "Add." Now you have an object which can be read by
/// ADO.NET.
///
public static void readExcel2(string fullpath) {
String sConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + fullpath + ";" + "Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
MessageBox.Show(sConnectionString);

try
{
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();

string sheetName = filename.Substring(0, filename.IndexOf(".xls"));
MessageBox.Show("sheetName: " + sheetName);

//OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [Sheet1$]", objConn);
OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [" + sheetName + "$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet objDataset1 = new DataSet();
objAdapter1.Fill(objDataset1);

string str = objAdapter1.ToString();
MessageBox.Show(str);

objConn.Close();
}
catch (Exception e) {
MessageBox.Show("error: " + e.Message);
}
}

///
/// Get Access Schema.
///
public void getSchema(string path)
{
int i, j;
string result = "";
DataTable userTables = null;
DataTable userTable = null;
System.Windows.Forms.TreeNode node = null;
System.Windows.Forms.TreeNode[] nc;

try
{
OleDbConnection conn = new OleDbConnection();
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path;
conn.Open();

userTables = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
new object[] {null, null, null, "TABLE"});

this.treeViewDBSchema.Nodes.Clear();
// Add list of table names to listBox
for (i=0; i < userTables.Rows.Count; i++)
{
result += userTables.Rows[i][2].ToString() + " { ";
userTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
new object[] {null, null, userTables.Rows[i][2].ToString(), null});

nc = new TreeNode[userTable.Rows.Count];
for (j = 0; j < userTable.Rows.Count - 1; j ++)
{
result += userTable.Rows[j][3].ToString() + ", "; // [2].ToString();
nc[j] = new TreeNode("Field: " + userTable.Rows[j][3].ToString());
nc[j].Tag = userTable.Rows[j][3].ToString();
}
// for the last item.
result += userTable.Rows[j][3].ToString(); // [2].ToString();
nc[j] = new TreeNode("Field: " + userTable.Rows[j][3].ToString());
nc[j].Tag = userTable.Rows[j][3].ToString();

result += " }\n";
node = new TreeNode("Table: " + userTables.Rows[i][2].ToString(), nc);
node.Tag = userTables.Rows[i][2].ToString();
this.treeViewDBSchema.Nodes.Add(node);
}
conn.Close();
//MessageBox.Show(this, result);
this.frmMain.setOutput(result);
}
catch (Exception ex)
{
MessageBox.Show(this, "Error: " + ex.Message);
}
}

C# work with local IP address

/// 
/// Ref: How To Get IP Address Of A Machine
/// Ref: WMI or How to change my IP address
/// using System.Management;
///

public string getLocalIP()
{
string localIP = "";
string strHostName = Dns.GetHostName();

IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
IPAddress [] addr = ipEntry.AddressList;

/* what if more than one instance exists? */
for (int i = 0; i < addr.Length; i++)
{
localIP = addr[i].ToString();
}

return localIP;
}


public bool setLocalIP(string newIP) {
try
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (!(bool) mo["IPEnabled"]) continue;
inPar = mo.GetMethodParameters("EnableStatic");
inPar["IPAddress"] = new string[] {newIP};
inPar["SubnetMask"] = new string[] {subnetMask};
outPar = mo.InvokeMethod("EnableStatic", inPar, null);
break;
}

this.currentIP = newIP;
return true;
}
catch (Exception e)
{
this.setErrMsg(e.Message + "\nsource: " + e.Source);
return false;
}
}


static void SwitchToDHCP()
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo["IPEnabled"] )
continue;

inPar = mo.GetMethodParameters("EnableDHCP");
outPar = mo.InvokeMethod( "EnableDHCP", inPar, null );
break;
}
}


static void SwitchToStatic()
{
string newIP;
string subnetMask = "255.255.255.0";
newIP = (curIP.Equals("192.168.168.209"))?"192.168.168.204":"192.168.168.209";

ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

inPar = mo.GetMethodParameters( "EnableStatic" );
inPar["IPAddress"] = new string[] { newIP };
inPar["SubnetMask"] = new string[] { subnetMask };
outPar = mo.InvokeMethod( "EnableStatic", inPar, null );
break;
}
}


static void ReportIP()
{
Console.WriteLine( "****** Current IP addresses:" );
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

Console.WriteLine( "{0}\n SVC: '{1}' MAC: [{2}]", (string) mo["Caption"],
(string) mo["ServiceName"], (string) mo["MACAddress"] );

string[] addresses = (string[]) mo[ "IPAddress" ];
string[] subnets = (string[]) mo[ "IPSubnet" ];

Console.WriteLine( " Addresses :" );
foreach(string sad in addresses)
Console.WriteLine( "\t'{0}'", sad );

Console.WriteLine( " Subnets :" );
foreach(string sub in subnets )
Console.WriteLine( "\t'{0}'", sub );

curIP = addresses[0];
}
}

C# GET/POST request, login, download, axWebBrowser

///
/// Example of HTTP Get request.
///
private string requestURL(string url, int timeout)
{
HttpWebRequest wr;
HttpWebResponse resp = null;
Stream stream;
StreamReader reader;
string strResponse = "";

try {
wr = (HttpWebRequest) WebRequest.Create(url);
wr.Timeout = timeout; // in milliseconds.
resp = (HttpWebResponse) wr.GetResponse();
stream = resp.GetResponseStream();
reader = new StreamReader(stream);
try { strResponse = reader.ReadToEnd(); }
finally { reader.Close(); }
resp = null;
}
catch (Exception ex) {
this.output_response("::" + ex.Message);
}
finally {
if (resp != null) resp.Close();
}
return strResponse;
}


///
/// Example of HTTP Post request.
/// Call the following function: e.g.
/// string html = HttpPost("http://abcde.com", "a=1&b=2");
///
private string HttpPost(string URI, string Parameters)
{
WebRequest req = WebRequest.Create(URI);
//req.Proxy = new System.Net.WebProxy(ProxyString, true);

req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";

byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;

Stream os = req.GetRequestStream ();
os.Write (bytes, 0, bytes.Length);
os.Close ();

WebResponse resp = req.GetResponse();
if (resp== null) return null;

StreamReader sr = new StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}


///
/// Example of using HTTP Post to log into a site.
///
private void login() {
HTMLDocument myDoc = new HTMLDocumentClass();
myDoc = (HTMLDocument) axWebBrowser1.Document;

try
{
HTMLInputElement oUser = null, oPass = null;

oUser = (HTMLInputElement) myDoc.all.item("username", 0);
oPass = (HTMLInputElement) myDoc.all.item("password", 0);

if (oUser == null || oPass == null) return;

oUser.value = "username_value";
oPass.value = "password_value";

HTMLFormElement frm = (HTMLFormElement) myDoc.all.item("login", 0);
frm.submit();

this.Task = 1;
}
catch (Exception ex)
{
this.showInfo("test() error: " + ex.Message);
}
}


///
/// Example of using HTTP Post to download an Excel file.
///
private void getExcel() {
HttpWebResponse resp = null;
Stream stream;
string filename = this.downloadFolder + "/download.xls";

try
{
wr = (HttpWebRequest) WebRequest.Create(this.excel_url);
wr.Method = "POST";
wr.ContentType = "application/x-www-form-urlencoded";
wr.ContentLength = byteArray.Length;
wr.Timeout = 100000; // in ms. Set this bigger than the site timeout value.
MyUtil.appendLog("wr.contentlength: " + wr.ContentLength);

wr.CookieContainer = new CookieContainer();
wr.CookieContainer.SetCookies(new Uri(this.excel_url) ,
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie.ToString());
MyUtil.appendLog("cookie: " +
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie);

// Send post request
Stream dataStream = wr.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
resp = (HttpWebResponse) wr.GetResponse();
resp.Cookies = wr.CookieContainer.GetCookies(resp.ResponseUri);
MyUtil.appendLog("resp status: " + resp.StatusDescription);

stream = resp.GetResponseStream();

//MyUtil.appendLog("resp header: " + resp.ContentType );
// Header: usually 'txt/html'. here is 'application/vnd.ms-excel'
StreamReader reader = new StreamReader(stream);
try
{
MyUtil.saveFile(filename, reader.ReadToEnd());
this.downloadSucceed = true;
}
catch (Exception ex)
{
MyUtil.FileDelete(filename);
this.downloadSucceed = false;
}
finally
{
reader.Close();
}
}
catch (Exception ex)
{
this.downloadSucceed = false;
MyUtil.FileDelete(filename);
}
finally
{
if (resp != null) { resp.Close(); }
}
}

///
/// Another way of navigating website: use the axWebBrowser control.
///
this.axWebBrowser1.Navigate(url);

[1] The user32 SendInput windows API. The SendInput function synthesizes
keystrokes, mouse motions, and button clicks to the currently active window.
[2] Capturing binary download via code through axwebbrowser1.

Tuesday, July 20, 2010

Sams Teach Yourself TCP/IP in 24 Hours

Sams Teach Yourself TCP/IP in 24 Hours (4th Edition) - by Joe Casad, 2008, 456 pages. ISBN-10: 0672329964.

I caught this book in sight at Barns and Noble. It is a short book to read, to the point and clear on basic concepts. Short is good.

I. TCP/IP basics

II. TCP/IP Protocol system

2. Correspondence of TCP/IP model and OSI model.
TCP/IP OSI Relevant protocols
----------------------------------------------------------------------------------
Application layer A,P,S
Transport layer T TCP/UDP
Internet layer N IP, ARP, RARP, ICMP, router(RIP, OSPF etc.)
Network access layer D,P FTS, FDDI, PPP, 802.11, 802.3, 802.16

note: 802.3 - ethernet, 802.11 - wireless, 802.16 - winmax

3. Network access layer
- physical addressing.
- LAN - ethernet.
CSMA/CS (Carrier Sense Multiple Access with Collision Detect)
ethernet frame: preamble|dest addr|sr addr|length|data|FCS(CRC)

4. Internet layer
- IP, IP header
- IP addressing: class A(8/24), B(16/16), C(24/8), D, E
- ARP (Address Resolution Protocol)
- RARP (Reverse ARP)
- ICMP
- BGP (Border Gateway Protocol), RIP (Routing Information Protocol)

5. Subnetting & CIDR (Classless Inter-Domain Routing)
- subnet mask/host ID
- split and combine networks.

6. Transport layer
- TCP/UDP
- ports, sockets
- multiplexing, demultiplexing.
- TCP: stream, resequencing, flow control, precedence & security, graceful close.

7. Application layer
- use socket/port to communicate with transport layer.
- target of multiplexing/de-multiplexing

III. Networking with TCP/IP

8. Routing
- routing table
- IP forwarding
- Dynamic routing algorithm
- DV (Distance vector). e.g. RIP
- LS (Link state). e.g. OSPF (Open Shortest Path First)
LS is more popular than DV now.
- Complex network routing
1) core router - backbone network (GGP)
2) exterior router - on border of autonomous systems (EGP: e.g. BGP)
3) interior router - within autonomous system (IGP: OSPF/RIP)
- classless routing: CIDR.
- OSPF: implemented as routed on unix/linux, builds SPT (Shortest Path Tree)

10. Firewall
- DMZ (Demilitarized Zone)
- rules
- proxy service
- reverse proxy

11. Name resolution
- DNS (Domain Name Server)

IV. TCP/IP utilities.

V. TCP/IP and the internet

18. Email
- outgoing email: SMTP
- incoming email: POP3/IMAP

19. Streaming and casting
- stack:
RTP
UDP
Internet layer
Network Access layer

VI. Advanced topics

C Traps and Pitfalls

C Traps and Pitfalls - by Andrew Koenig, 1989, 160 pages. ISBN-10: 0201179288.

Andrew Koenig wrote a small reference manual on C programming based on his experience when he worked at AT&T lab. Since it received wide acceptance, he added more material and resulted in this book. It's highly recommended to any serious C programmers. Some contents are kind of outdated, such as those about problems of early day compilers. But many points are still ubiquitously applicable.

- Introduction

- Chapter 1. Lexical pitfalls
1.3 greedy principle in evaluating statement.
e.g. a --- b is: a-- - b,
y = x/*p is: y=x plus the start of a comment!
Should write as y = x / *p or y = x / (*p).
a +++++ b is: a++ ++ + b. This has compile error since a++ is not l-value.
Be careful, if a number starts with 0, it's an octal number.

- Chapter 2. Syntax pitfalls
2.1 Function declaration.
This casts address 0 as the pointer to function void f() and call it.
(* (void (*)()) 0)();
2.2 Operator precedence.
if (a == 'a' || b = 'b' || c == 'c') {} is equivalent to:
if ((a == 'a' || b) = ('b' || c == 'c')) {}
2.6 dangling else.
if (a)
if (b) b ++;
else { c ++; }
is equivalent to:
if (a) {
if (b) b ++;
else { c ++; }
}

Chapter 3. Semantic pitfalls
3.6 off-by-1 error - is the most prevalent.
One solution in C: 0-based C array, using asymmetric boundary.
e.g. x >= 16 && x < 38. 38-16 is exactly the size of the range.
3.9 Check overflow.
method 1: if ((unsigned) a + (unsigned) b > INT_MAX) // overflowed
method 2: if (a > INT_MAX - b) // overflowed

Chapter 4. Linking
lint.

Chapter 5. Library functions
5.1 int getchar() - return types does not match function, can cause problem.
5.2 I/O buffer.
setbuf(stdout, (char *) 0); // no buffer
5.4 errno
5.5 signal, longjmp

Chapter 6. Preprocessor
- macro
- use of -- or ++ can cause unexpected side effects in macro.
6.3 assert
#define assert(e) \
((void) ((e) || _assert_error(__FILE__, __LINE__)))

Chapter 7. Portability
7.5 >> and divide by 2. >> is faster and works correctly when var is positive.
e.g. replace "mid = (left + right) / 2" with "mid = (left + right) >> 1".
7.11 literal string can represent an array.
e.g. "0123456789"[n%10] is equivalent to: a[] = "0123456789"; a[n%10];
This is used in systems where 0-9 may not be consecutive.

Chapter 8. Suggestions and answers.
- Optimize binary search:
1) use >> instead of 1/2, 2) use pointer instead of array indexing.
- Little/big ending.
- getchar(), putchar() have both macro and function definitions. macro is faster.
- atol().

Appendix A
- printf. %p, %n, %06d is equivalent to %.6d in most cases.
- varargs
- stdarg

Author's suggestions on using C++:
- avoid pointer
- use library
- use class

Blog Archive

Followers