if len==0, buff may be NULL